最近の CPU は、更新された順序で常にデータをメモリに書き込むとは限りません。
a = 1
b = a + 1
...CPUはb
、メモリに書き込む前にメモリに書き込む可能性がありa
ます。上記のコードを実行しているスレッドは、割り当てが行われると、どちらの変数の古い値も認識しないため、単一のスレッドで実行する限り、これは実際には問題になりません。
マルチスレッドは別の問題です。次のコードでは、別のスレッドが重い計算の値を取得できると思います。
a = heavy_computation()
b = DONE
...他のスレッドが...
repeat while b != DONE
nothing
result = a
ただし、問題は、結果がメモリに格納される前に完了フラグがメモリに設定される可能性があるため、計算結果がメモリに書き込まれる前に、他のスレッドがメモリアドレス a の値を取得する可能性があることです。
同じ問題が発生し、「前に発生する」という保証がない場合はThread.start
、Thread.join
次のようなコードで問題が発生します。
a = 1
Thread.start newthread
...
newthread:
do_computation(a)
...a
スレッドの開始時に値がメモリに格納されていない可能性があるためです。
ほとんどの場合、新しいスレッドが開始前に初期化したデータを使用できるようにする必要があるため、Thread.start
には「発生前」の保証があります。つまり、呼び出し前に更新されたデータはThread.start
、新しいスレッドで使用できることが保証されています。同じことが、新しいスレッドによって書き込まれたデータが、終了後にそのスレッドに参加するスレッドに見えることが保証されている場合にも当てはまりThread.join
ます。
スレッド化がはるかに簡単になります。