2つの場合を除いて、それが見えるかもしれませほど単純ではありません。
- リーダーとなしの作家のみが存在する場合、あなたは、同期するためのない必要性を行います。
- 複数のスレッドに書き込みがあり、それらのうちの少なくとも1人が読み取り - 変更 - 書き込み操作(たとえば
++x;
)を実行している場合は、常にを同期する必要があります。他のすべての場合には
、あなたが少なくとも一つの作家とリーダー(またはいくつかの作家を)持っている場合、あなたは通常(非常に少数の例外を除いて)アクセスを同期する必要がありますが、必ずしも常に、および必ずしも厳密に可能な方法ではありません。
これは、必要な保証によって大きく異なります。アプリケーションによっては、スレッドに対して厳密なシーケンシャル整合性が必要なものがあります(また、ロックの公正さが必要な場合もあります)。アプリケーションによっては、同じスレッド内での保証の前に、うまく動作しますが、パフォーマンスが大幅に向上するアプリケーションもあります。しかし、他のアプリケーションでさえもそれほど必要ではなく、リラックスした操作や完全な保証なしでは完全に満足しています。例えば
、ワーカースレッドのこの「典型的な」実装では、作家と読者を持っています
// worker thread
running = true;
while(running) { task = pull_task(); execute(task); }
// main thread exit code
running = false;
join(workerthread);
これは、任意の同期せずに完璧に適しています。確かに、running
の値が変更される時期や方法は変わっていませんが、実際には違いはありません。メモリ位置にある程度の「ランダム」な中間値を持つ方法はなく、ワーカースレッドがタスクを実行中である可能性が最も高いため、変更が数十ナノ秒前またはそれ以降に見えるかどうかは重要ではありません。最悪の場合、それは数ミリ秒後に変化を拾う。最終的に、次の反復で、ワーカースレッドはに変更を受け取り、終了します。
Dr. Dobbに掲載されたSPSC早送りキューは、数年前に同様の原則に基づいていました。
多くの異なる同期モードでの良好で包括的な読み取りとその意味は、GCC documentationに記載されています。
ケース2および3、すなわち、少なくとも1つのスレッドが少なくとも1つの他のスレッドの読み取りまたは書き込みによって書き込んでいる状況。 – juanchopanza
異なるスレッドのデータにアクセスするときに常にロックする必要はありません。アトミック操作、特にC++ 11の 'std :: atomic'を見てください。 – nijansen
そして、最後の文に対処するために、マルチコアCPU上で、さまざまなレベルのキャッシュにそれぞれの値のコピーが複数存在することがあります。 – Hulk