系統呼叫和上下文交換
使用者程式如何向核心發出請求?
該部落格上撰寫的文章是出於教學目的而創建的。 另外,文章中的資訊可能不正確,請謹慎。
用戶態程式不能直接控制磁碟或網路設備。 相反,它向作業系統請求工作,這種正式的請求方法稱為系統呼叫。
它與常規函數呼叫有何不同?
一般函數呼叫僅更改同一權限區域內的執行位置。 對於系統調用,CPU權限從用戶態轉變為核心態,核心處理完請求後又返回用戶態。
通用函數呼叫
使用者代碼→使用者功能→使用者代碼
系統調用
使用者代碼→核心入口→權限與參數檢查→核心操作→使用者代碼
開啟檔案、記憶體映射、套接字通訊、行程建立等功能最終都會用到系統呼叫。 程式設計師通常會呼叫作業系統API或標準函式庫,並在下面的層中執行對應的系統呼叫。
它與上下文切換不同
呼叫系統呼叫並不一定會改變到另一個進程。 同一個執行緒可能會進入核心模式,處理請求,然後立即返回。
上下文切換是透過儲存目前執行狀態並恢復另一個執行緒或進程的狀態來改變執行目標的過程。
系統呼叫:同一個執行器向核心請求工作。
上下文切換:CPU改變主體本身來執行
然而,需要等待檔案或網路資料的系統呼叫可以使當前執行緒處於等待狀態。 同時,作業系統會執行其他執行緒以避免浪費CPU,此時可能會發生上下文切換。
系統調用不是免費的
權限切換和參數檢查都是要花錢的。 這就是為什麼在緩衝區中收集小資料並一次寫入比一個位元組寫入數千次更有利的原因之一。
std::string buffer;
for (const auto& line : lines)
{
buffer += line;
buffer += '\n';
}
file.write(buffer.data(), buffer.size());
然而,這並不意味著應該不惜一切代價避免系統呼叫。 它是作業系統安全管理資源的必要邊界,當發現效能問題時,最好查看呼叫和等待方法的數量。