2016-04-08 11 views
2

なぜ私がこれを求めているのかについての背景。私は数時間前にこの質問をした非同期I/Oを実行するとき、カーネルはI/O操作が完了したかどうかをどのように判断しますか?

は、すべてのI/Oは、システムコールを介して行われなければならない答えを持っていたし、道のシステムコールが行くに実装されている

When a goroutine blocks on I/O how does the scheduler identify that it has stopped blocking?

は、彼らは常に呼ばれていますランタイムによって制御されるコードを通じて実行されます。これは、システムコールを呼び出すときに直接コールするのではなく(カーネルにスレッドの制御を渡す)、ランタイムには作成するシステムコールが通知され、それがゴルーチンのために実行されることを意味します。これは、例えば、ブロックされていないシステムコールではなく、ブロックされていないシステムコールを行うことができます(基本的にはカーネルに "このことをしてください。終了するまでブロックする代わりにすぐに戻り、準備ができました ")。その間に他の作業を続けることができます。


だから、私の理解から、何golangスケジューラが行うことは、それがI/O操作のために待機しているスレッドの上にハングアップ過ごす時間を取得するかわからないなることです。代わりに、何とかその責任をカーネルに委ねます。

しかし、私には不明なことがたくさんあるので、このプロセスをより深く理解したいと思います。

これは私の理解であり、潜在的に完全に間違っている可能性があります。ゴルーチン内部

    、リモートサーバーへのGETリクエストとして
  1. メイクI/O要求
  2. Golangは、ブロック操作であるTCPストリームを、読むためにシステムコールを行い、代わりに待つので、それはカーネルに依頼それが情報を得たときに通知される。スケジューラはキューからブロックしているゴルーチンを取り除きます。
  3. カーネルがすべての情報を取得すると、それはgoプロセスに転送され、スケジューラはそのキューにゴルーチンを追加するように通知します。

私が理解しようとしているのは、別のスレッドを作成せずにI/O操作を行う方法と、カーネルがI/O操作を実際に「知っている」方法です。それはポーリングを介してですか、あるいはそこに何らかの割り込みシステムがありますか?

これは意味があると思います。私はこの低レベルのコンセプトにはとても新しいです。

答えて

2

以下のカーネルは、「カーネル側」を意味します。これは、OSのカーネル+ロードされたドライバを含みます。

リモートサーバーへのTCP接続があるとします。カーネルが非同期の書き込み/読み取りTCPストリームを処理する方法の例を以下に示します。

バイト配列をTCPストリームに送信すると、カーネルはバッファストリームをRAMに入れ、DMAシステムを制御してバッファをネットワーキングカードにコピーします。 DMAがそのジョブを完了すると、CPU内部の割り込みが呼び出されます。カーネルによって登録された割り込みハンドラは、DMAからの信号をTCPストリームメソッドへの書き込みの完了コールバックに変換します。もちろん、実際のTCPスタックははるかに複雑です。これらの文章は、そのことがどのように機能するかという単なる考えです。

TCPストリームから読み取ったケースでは、ネットワーキングカードにパッケージが入ったときに別の割り込みが呼び出されます。カーネルによって登録された別のハンドラは、golang側で割り込みをイベントに変換します。

また、実際のケースは非常に複雑です。多くのOS、多くのバージョン、多くの種類のIO操作、多くのハードウェアデバイスがあります。

関連する問題