7

Goのバッファリングされたチャネルは、基本的にスレッドセーフなFIFOキューです。(Goのバッファリングされたチャネルをスレッドセーフキューとして使用することは可能ですか?を参照してください。 )

どのように実装されているのだろうか。「複数の読み取りまたは書き込みスレッド用のロックレスキューなどはありますか?」で説明されているように、ロックフリーですか??

Goのsrcディレクトリ(grep -r Lock .|grep chan)でgrepを実行すると、次の出力が得られます。

./pkg/runtime/chan.c:   Lock;
./pkg/runtime/chan_test.go: m.Lock()
./pkg/runtime/chan_test.go: m.Lock() // wait
./pkg/sync/cond.go: L Locker // held while observing or changing the condition

ただし、私のマシン(MacOS、Intel x86_64)をロックすることはありません。これを検証するための公式リソースはありますか?

4

2 に答える 2

8

chan.cruntime·chansendの関数を読むと、チャネルがバッファリングされているかどうかを確認するためのチェックの前に呼び出されていることがわかります。runtime·lockif(c->dataqsiz > 0)

つまり、バッファリングされたチャネル(および一般にすべてのチャネル)はロックを使用します。

検索で見つからなかった理由は、大文字のLが付いた「ロック」を探していたためです。チャネルに使用されるロック関数は、ランタイムではエクスポートされないC関数です。

于 2012-10-27T18:51:50.777 に答える
7

好きなものすべてに対して、ロックフリー(さらには待機なし!)の実装を作成できます。CMPXCHGのような最新のハードウェアプリミティブは、普遍的に使用できるのに十分です。しかし、そのようなアルゴリズムを作成して検証することは、最も簡単な作業の1つではありません。それに加えて、はるかに高速なアルゴリズムが存在する可能性があります。ロックフリーアルゴリズムは、一般にアルゴリズムのごく一部にすぎません。

私が覚えている限り、Dmitry Vyukovは過去にGo用のロックフリーMPMC(マルチプロデューサー/マルチコンシューマー)チャネル実装を作成しましたが、Goのselectステートメントに問題があるため、パッチは破棄されました。この声明を効率的にサポートすることは本当に難しいようです。

ただし、Goのチャネルタイプの主な目標は、幅広い問題に簡単に使用できる高レベルの同時実行プリミティブを提供することです。並行プログラミングの専門家ではない開発者でも、大規模なソフトウェアプロジェクトで簡単にレビューおよび保守できる正しいプログラムを作成できる必要があります。パフォーマンスの最後のビットをすべて絞り出すことに関心がある場合は、ニーズに合った専用のキュー実装を作成する必要があります。

于 2012-10-28T00:10:07.417 に答える