immutableデータを信頼して、メッセージパッシングを使ってスレッドを同期するのが
Dでのマルチスレッディングの好ましいやり方ですが、この言語は型システムサポートと同じように、
複数のスレッドからアクセスされるオブジェクトにマークするsharedによる
プリミティブな同期の組み込みサポートを持ちます。
shared型識別子は変数が異なるスレッド間で共有されるとマークします:
shared(int)* p = new int;
int* t = p; // エラー
たとえばstd.concurrency.sendはimmutableまたはsharedのデータ
のみを送り、送られるメッセージをコピーします。sharedは推移的で、従ってclassまたはstruct
がsharedマークされた時、そのすべてのメンバもマークされます。static変数はスレッド局所記憶
(TLS)を使って実装されており、各スレッドは自分専用の変数を得るためデフォルトでは
sharedではないことに注意してください。
synchronizedブロックでコンパイラに、一度に1つのスレッドのみが入れる
クリティカルセクションを作るよう指示できます。
synchronized {
importStuff();
}
classメンバ関数の中でこれらのブロックは競合を減らすためにsynchronized(member1, member2)
によって異なるメンバオブジェクトミューテックスに制限されることがあります。Dコンパイラは自動的に
クリティカルセクションを挿入します。クラス全体も同じようにsynchronizedとしてマークされ、
コンパイラは一度に1スレッドのみがその実際のインスタンスにアクセスするようにします。
shared変数の不可分操作はcore.atomic.atomicOpヘルパを使って行うことができます:
shared int test = 5;
test.atomicOp!"+="(4);