あなたは間違っていると聞いた。"i++"
特定のコンパイラや特定のプロセッサアーキテクチャではスレッドセーフである可能性がありますが、標準ではまったく義務付けられていません。実際、マルチスレッドはISO CまたはC ++標準(a)の一部ではないので、コンパイルする対象に基づいてスレッドセーフであると見なすことはできません。
次の++i
ような任意のシーケンスにコンパイルできることは非常に現実的です。
load r0,[i] ; load memory into reg 0
incr r0 ; increment reg 0
stor [i],r0 ; store reg 0 back to memory
これは、メモリ増分命令を持たない私の(仮想の)CPUではスレッドセーフではありません。または、それは賢く、次のようにコンパイルできます。
lock ; disable task switching (interrupts)
load r0,[i] ; load memory into reg 0
incr r0 ; increment reg 0
stor [i],r0 ; store reg 0 back to memory
unlock ; enable task switching (interrupts)
ここlock
でunlock
、割り込みを無効および有効にします。しかし、それでも、これらのCPUが複数メモリを共有しているアーキテクチャでは、これはスレッドセーフではない可能性があります(lock
1つのCPUの割り込みのみを無効にする場合があります)。
言語自体(または、言語に組み込まれていない場合はライブラリ)はスレッドセーフな構造を提供します。生成されるマシンコードの理解(または誤解)に依存するのではなく、それらを使用する必要があります。
(a)を調べる必要があるのは、Java synchronized
やpthread_mutex_lock()
(一部のオペレーティングシステムではC / C ++で利用可能)などです。
(a)この質問は、C11およびC ++ 11標準が完了する前に行われました。これらの反復により、アトミックデータ型を含むスレッド仕様が言語仕様に導入されました(ただし、それらと一般にスレッドは、少なくともC ではオプションです)。