非同期I/Oはプロセッサ時間を介しselect()
て動作し、poll()
プロセッサ時間を使用しないことを理解しています。つまり、ビジーループではありませんが、これらは実際に内部でどのように実装されていますか?それはどういうわけかハードウェアでサポートされていますか?それはなぜこれらを使用するための明らかなプロセッサコストがあまりないのですか?
2 に答える
select
/が何poll
を待っているかによります。いくつかのケースを考えてみましょう。簡略化のためにシングルコアマシンを想定します。
まず、が別のプロセスを待機している場合を考えselect
ます(たとえば、他のプロセスが何らかの計算を実行してから、パイプラインを介して結果を出力する場合があります)。この場合、カーネルはプロセスを入力を待機しているものとしてマークするため、プロセスにCPU時間を提供しません。他のプロセスがデータを出力すると、カーネルはプロセスをウェイクアップし(CPUに時間を与える)、入力を処理できるようにします。最近のOSはプリエンプティブマルチタスクを使用しているため、これは他のプロセスがまだ実行されている場合でも発生します。つまり、カーネルは定期的にプロセスを中断して、他のプロセスにCPUを使用する機会を与えます(「タイムスライシング」)。
select
がI/Oを待機しているときに画像が変わります。たとえば、ネットワークデータ、またはキーボード入力。この場合、古風なハードウェアは入力を待機するCPUを回転させる必要がありますが、最新のハードウェアはすべて、ハードウェアが割り込み(カーネルが処理する特別に処理されるイベント)を提供するまで、CPU自体を低電力の「待機」状態にすることができます。割り込みハンドラーでは、CPUは着信データを記録し、割り込みから戻った後、プロセスをウェイクアップしてデータを処理できるようにします。
ハードウェアのサポートはありません。ええと、あります...しかし、特別なことは何もありません、そしてそれはあなたが見ているファイル記述子の種類に依存します。関係するデバイスドライバーがある場合、実装はドライバーやデバイスによって異なります。たとえば、ソケット。一部のデータが読み取られるのを待つ場合、一連のイベントがあります。
- 一部のプロセスは、poll()/ select()/ epoll()システムコールを呼び出して、ソケット内のデータを待機します。ユーザーモードからカーネルへのコンテキストスイッチがあります。
- パケットが到着すると、NICはプロセッサに割り込みます。ドライバの割り込みルーチンは、パケットをキューの後ろにプッシュします。
- そのキューからデータを取得し、カーネル内のネットワークコードをウェイクアップして、そのパケットを処理するカーネルスレッドがあります。
- パケットが処理されると、カーネルはそれを予期していたソケットを判別し、データをソケットバッファーに保存して、システムコールをユーザースペースに戻します。
これは非常に簡単な説明であり、多くの詳細が欠落していますが、要点を理解するにはそれで十分だと思います。
ドライバーが関与しない別の例は、UNIXソケットです。それらの1つからのデータを待機すると、待機するプロセスがリストに追加されます。ソケットの反対側にある他のプロセスがデータを書き込むと、カーネルはそのリストをチェックし、ポイント4が再度適用されます。
お役に立てば幸いです。例がそれを理解するのに最適だと思います。