これはマルチスレッド環境で非干渉になりますか?
質問のテキストでは、dq
(関数内の他のすべての変数と同様に)ローカルオブジェクトです。
std::deque<T> dq;
これが本当に当てはまる場合、質問の答えは簡単です: 「はい」 . 競合がないため、スレッドセーフです。各スレッドはローカル オブジェクトで動作し、共有がないため、データ競合が発生することはありません。
あなたのコードが共有データ構造の使用を示すことを意図しており、それdq
が実際にはグローバルオブジェクトか、何らかの方法で複数のスレッドから同時にアクセスできるものであると仮定すると (これはdq->size()
関数呼び出しが示唆しているように見えます)、答えは「依存します」です。 " .
すべてのスレッドが、表示している関数のみを同時に実行していてdq
、 への参照またはポインターでconst
const
あり、関数に非メンバー関数への呼び出しが含まれていない場合、答えは「はい、しかし、この場合、クリティカルセクションはまったく必要ありません。」パラグラフ 17. C++11 標準の 6.5.9/3 では、次のように指定されています。
const
C++ 標準ライブラリ関数は、現在のスレッド以外のスレッドからアクセス可能なオブジェクト (1.10) を直接的または間接的に変更してはなりませんthis
。
データ競合とは何かを定義するパラグラフ 1.10 (特に 1.10/21) への参照は、上記のパラグラフの意味をより明確にします。
プログラムの実行にデータ競合が含まれているのは、異なるスレッドに競合する 2 つのアクションが含まれており、そのうちの少なくとも 1 つがアトミックではなく、どちらも他のスレッドの前に発生しない場合です。このようなデータ競合は、未定義の動作を引き起こします。[...]
最後に、パラグラフ 1.10/4 は、2 つのアクションが競合する場合を指定します。
2 つの式の評価は、一方がメモリ ロケーション (1.7) を変更し、もう一方が同じメモリ ロケーションにアクセスまたは変更する場合に競合します。
これらすべてから、const
メンバー関数は必然的にスレッドセーフであることがわかります。Herb Sutter によるこのプレゼンテーションをご覧になることをお勧めします。
deque<T>::size()
はconst
メンバ関数であり、はat()
への参照を返すconst
メンバ関数 ( への参照またはポインタから呼び出しているため) であるため、複数のスレッドからのアクセスを同期する必要はありません。const
const
yourdq
がへの参照またはポインターでないconst
場合、 は非メンバー関数であるため、答えは「いいえ」です。さらに、は要素への非 const 参照であるため、「操作」は non- になる可能性があり、それ自体ではなくの要素にデータ競合が発生します。at()
const
v
v
const
dq
dq
同様に、スレッドが同時にdq
他の関数にアクセスして変更している場合、共有オブジェクトへのすべてのアクセスを保護しているわけではないため、答えはやはり「いいえ」です。読み取り操作は書き込み操作と競合し (上記を参照)、それらの一部のみを保護しています。この場合、クリティカル セクションはwhile
サイクル全体にまたがる必要があります。