次の構造は、foo の要素が適切に配置され、サイズが適切に設定されているため、単語のティアリングが発生しないと仮定すると、スレッドセーフですか? そうでない場合、なぜですか?
注: 以下のコードは、私がやりたいことのおもちゃの例であり、実際の現実のシナリオではありません。明らかに、私の例で観察可能な動作をコーディングするより良い方法があります。
uint[] foo;
// Fill foo with data.
// In thread one:
for(uint i = 0; i < foo.length; i++) {
if(foo[i] < SOME_NUMBER) {
foo[i] = MAGIC_VAL;
}
}
// In thread two:
for(uint i = 0; i < foo.length; i++) {
if(foo[i] < SOME_OTHER_NUMBER) {
foo[i] = MAGIC_VAL;
}
}
これは一見すると明らかに安全ではないように見えるので、安全であると考える理由を強調します。
- foo の要素を変更しないか、MAGIC_VAL に設定するかの 2 つのオプションしかありません。
- 更新中にスレッド 2 が中間状態の foo[i] を検出した場合、発生する可能性があるのは次の 2 つだけです。中間状態が <である
SOME_OTHER_NUMBER
か、そうでないかです。< の場合SOME_OTHER_NUMBER
、スレッド 2 も MAGIC_VAL に設定しようとします。そうでない場合、スレッド 2 は何もしません。
編集: また、foo が long や double などの場合はどうすればよいでしょうか? アラインメントなどは、foo の 1 つの要素を更新しても他の要素に影響を与えないようなものであるとまだ想定しているかもしれません。また、この場合のマルチスレッドの要点はパフォーマンスであるため、どのタイプのロックもこれを無効にします。