1

一方のスレッドがプロデューサーで、もう一方のスレッドがコンシューマーであるプロデューサー/コンシューマーキューを作成する最も効率的な方法は何ですか。ある論文で、著者は、キューに要素を挿入するために1つの不可分操作が必要であると述べましたが、その方法については説明していません。

また、彼のキューは循環キューであり、コンシューマーはキューが空の場合に待機し、プロデューサーはキューがいっぱいの場合に待機します。彼はどうやってそのようなキューを実装できたのでしょうか。アトミック操作とは、ある種のミューテックスを意味するのでしょうか、それとも単にアトミック変数を意味するのでしょうか。彼が言ったことに注意してください、1つの不可分操作。

4

1 に答える 1

1

ロックレスキューの実装経験がない場合、唯一の答えは次のとおりです。最も効率的な(そして安全な)方法は、pthread(mutexまたはcond var)によって提供されるロックを使用することです。

ロックレスアルゴリズムは通常(必ずしもそうとは限りませんが)少し余分なパフォーマンスを提供しますが、何をしているのか正確にわからない場合は、ひどく間違ってしまう可能性があります。

一方、Linuxでのphtreadsの実装は、可能な場合はロックを回避しfutex、必要なときに使用します(これfutexも高速ですが、何をしているのかを知っておく必要があります)。
このようなキューは、1秒あたり10万のタスクを渡すのに問題はありません。これは制限のように思えるかもしれませんが、実際には1秒あたり1,000万のタスクを渡す必要がある場合、それは間違っています。理想的には、キューで1秒あたり数十から100程度のタスクを渡すことになるでしょう(タスクは少なくなりますが、ワークグループは大きくなります)。たとえば、1バイトのデータを処理する2500万のタスクではなく、それぞれ0.5メガバイトのデータを処理する50のタスクを作成するとします。

それでもロックレス実装を試してみることを主張する場合(おそらく学術的な関心から)、アトミック比較交換操作が必要になります(CのGCCドキュメントで「レガシー__sync関数」を検索してください。C++の場合は新しいものを使用しますアトミックオペレーション)。
ABAのような微妙な詳細を必ず読んでください。通常、何らかのポインタ操作(下位3ビットにrefcountを格納する)または明示的な参照カウントを使用したダブルワード交換が必要です。

あるいは、いくつかの仮定を行う場合、ロックレスキューは、アトミック追加のみで、またはアトミック操作なしで実装できます(好奇心だけに関心がある場合は、「早送りキュー」を参照してください)。ただし、これらは仮定が当てはまる場合にのみ機能し、さらにエラーが発生しやすいため、これらから遠ざけることをお勧めします。

于 2012-07-06T12:29:24.397 に答える