88

Go 言語仕様、効果的な Go、および Go メモリ モデルを (簡単に) 確認した後でも、Go チャネルが内部でどのように機能するかについてはまだ少し不明です。

それらはどのような構造ですか?それらは、スレッドセーフなキュー/配列のように機能します。

それらの実装はアーキテクチャに依存しますか?

4

4 に答える 4

94

チャネルのソース ファイルは (go ソース コード ルートから) /src/pkg/runtime/chan.goにあります。

hchanチャネルの中心的なデータ構造であり、送信および受信のリンクされたリスト (ゴルーチンとデータ要素へのポインターを保持) とclosedフラグを持ちます。Lockruntime2.go で定義され、OS に応じてミューテックス (futex) またはセマフォとして機能する埋め込み構造があります。ロックの実装は、ビルド タグに基づいて、lock_futex.go (Linux/Dragonfly/一部の BSD) または lock_sema.go (Windows/OSX/Plan9/一部の BSD) にあります。

チャネル操作はすべてこの chan.go ファイルに実装されているため、makechan、send および receive 操作のほか、select コンストラクト、close、len、および cap ビルトインを確認できます。

チャネルの内部動作に関する非常に詳細な説明については、 Dmitry Vyukov 自身による強力なGo チャネルを読む必要があります(とりわけ、Go コア開発者、ゴルーチン、スケジューラ、およびチャネル)。

于 2013-10-27T20:23:29.800 に答える
7

次の 2 つの質問をしました。

  1. それらはどのような構造ですか?

Go のチャネルは実際には「スレッドセーフなキューのようなもの」です。より正確に言うと、Go のチャネルには次のプロパティがあります。

  • ゴルーチンセーフ
  • FIFO セマンティクスを提供する
  • ゴルーチン間で値を保存して渡すことができます
  • ゴルーチンにブロックとブロック解除をさせる

チャネルを作成するたびに、hchan構造体がヒープに割り当てられ、チャネルとして表される hchan メモリ位置へのポインターが返されます。これが、go-routine がそれを共有できる方法です。

上記の最初の 2 つのプロパティは、ロック付きのキューと同様に実装されます。チャネルがさまざまな go-routine に渡すことができる要素は、hchan 構造体のインデックスを持つ循環キュー (リング バッファー) として実装されます。インデックスは、バッファー内の要素の位置を説明します。

循環キュー:

qcount   uint           // total data in the queue
dataqsiz uint           // size of the circular queue
buf      unsafe.Pointer // points to an array of dataqsiz elements

そしてインデックス:

sendx    uint   // send index
recvx    uint   // receive index

go-routine がチャネル構造にアクセスしてその状態を変更する必要があるたびに、ロックを保持します。たとえば、要素をバッファにコピーしたり、バッファからコピーしたり、リストやインデックスを更新したりします。一部の操作はロックフリーになるように最適化されていますが、これはこの回答の範囲外です。

go チャネルのブロックとブロック解除のプロパティは、ブロックされた go ルーチンを保持する 2 つのキュー (リンクされたリスト) を使用して実現されます。

recvq    waitq  // list of recv waiters
sendq    waitq  // list of send waiters

go-routine が完全なチャネル (バッファがいっぱい) にタスクを追加したり、空のチャネル (バッファが空) からタスクを取得したりするたびに、疑似 go-routine sudog構造体が割り当てられ、go-routineそれに応じて、sudog をノードとして送信または受信待機リストに追加します。gopark次に、go-routine は特別な呼び出しを使用して go ランタイム スケジューラを更新します。これは、いつ実行を中止するか ( )、いつ実行できるようにするか( )を示唆しgoreadyます。これは非常に単純化された説明であり、いくつかの複雑さが隠されていることに注意してください。

  1. それらの実装はアーキテクチャに依存しますか?

@mnaが既に説明した OS 固有のロックの実装に加えて、アーキテクチャ固有の制約の最適化や違いについては知りません。

于 2022-02-02T16:15:08.013 に答える