2012-10-27 9 views
6

Goのバッファされたチャネルは、基本的にスレッドセーフなFIFOキューです。 (Is it possible to use Go's buffered channel as a thread-safe queue?を参照してください)Goのバッファリングされたチャネルはロックレスですか?

どのように実装されているのだろうか。それはIs there such a thing as a lockless queue for multiple read or write threads?に記載されているようにロックフリーですか?ゴーのsrcディレクトリ(grep -r Lock .|grep chan)にgreping

は、次のような出力が得られます。

./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の、インテルx86_64版)にロックすることはありません。これを検証する正式なリソースはありますか?

答えて

6

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

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

大文字のLを使用して「ロック」を検索していたため、検索で見つからなかった理由です。チャネルで使用されるロック機能は、実行時にはエクスポートされていないC関数です。

+0

ありがとうございます!なぜそれがロックフリーとして実装されていないかについてのアイデア? –

+0

"Lockfree"はより良いパフォーマンスを意味しません。また、ロックの理由を考えるのも簡単です。競合が高かった場合、おそらくLockメソッドが高速になります。 –

+0

ありがとう、@ stephen-weinberg。それは今より意味をなさない。 –

3

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

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

しかし、Goのチャネルタイプの主な目標は、幅広い問題に簡単に使用できる高水準の同時実行プリミティブを提供することです。並行プログラミングの専門家ではない開発者であっても、大規模なソフトウェアプロジェクトで容易に見直され維持される正しいプログラムを書くことができなければなりません。最後のすべてのパフォーマンスを搾取することに興味がある場合は、ニーズに合った特別なキュー実装を作成する必要があります。

関連する問題