システムコールとコンテキスト交換
ユーザープログラムはどのようにカーネルにタスクを要求するのですか?
本ブログ作成文は、講義を目指して製作されました。 また、作成された文章の情報も間違っている可能性がありますので、ご注意ください。
ユーザーモードプログラムはディスクやネットワークデバイスを直接制御できません。 代わりにオペレーティングシステムに作業を要求するが、この公式な要求方法をSystem Call(システムコール)と呼ぶ。
一般的な関数呼び出しとは何が違うのですか?
一般関数呼び出しは、同じ権限領域内で実行位置のみを変更します。 システムコールはユーザーモードからカーネルモードにCPU権限が変更され、カーネルが要求を処理した後、再度ユーザーモードに戻ります。
汎用関数呼び出し
ユーザーコード→ユーザー関数→ユーザーコード
システムコール
ユーザーコード→カーネルエントリ→権限と因子チェック→カーネル操作→ユーザーコード
ファイルオープン、メモリマッピング、ソケット通信、プロセス生成などの機能は、最終的にシステムコールを使用します。 プログラマは通常オペレーティングシステムAPIまたは標準ライブラリを呼び出し、その下の階層で適切なシステムコールが実行されます。
Context Switchとは異なる
システムコールを呼び出したとは必ずしも別のプロセスに変わるわけではありません。 同じスレッドがカーネルモードに入り、要求を処理してすぐに戻ることもできます。
Context Switch(コンテキスト交換)は、現在の実行状態を保存し、他のスレッドやプロセスの状態を復元して実行対象を変更する作業です。
システムコール:同じ実行主体がカーネルに仕事を要求する
コンテキスト交換:CPUが実行する主体自体を変える
ただし、ファイルやネットワークデータを待たなければならないシステムコールは、現在のスレッドを待機状態にすることができます。 その間、オペレーティングシステムはCPUを悩ませないように別のスレッドを実行し、このときコンテキスト交換が発生する可能性があります。
システムコールは無料ではありません
権限転換と因子検査には費用がかかる。 小さなデータを1バイトずつ数千回書き込むよりもバッファに集めて一度に書き込むほうが有利な理由の一つだ。
std::string buffer;
for (const auto& line : lines)
{
buffer += line;
buffer += '\n';
}
file.write(buffer.data(), buffer.size());
しかし、システムコールを無条件に避けなければならないという意味ではありません。 オペレーティングシステムがリソースを安全に管理するためには必ず必要な境界であり、パフォーマンスの問題が確認されたときの呼び出し回数と待機方式を調べるのが良い。