D 言語はマルチスレッドプログラミングのための機能を言語自身が持っている.
synchronized{...}
クリティカルセクションを作成できる. このブロックの中の文は同時に一つのスレッド しか実行することができなくなる.
multi_thread.d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import std.stdio;
import core.thread;
class ShareData{
private int v;
public void increase(){
synchronized{
int a = v;
foreach(i; 0..10){
v = v + i;
}
}
}
public int value() const{
return v;
}
}
class IncrementThread : Thread{
private ShareData sd;
public this(ShareData sd){
this.sd = sd;
super(&f);
}
private void f(){
sd.increase();
}
}
void main(){
// 全部のスレッドで共有するデータ
auto sd = new ShareData;
// 10 個のスレッドを次々に作って実行開始
Thread[] threads;
foreach(i; 0..10){
auto t = new IncrementThread(sd);
threads ~= t;
t.start();
}
foreach(t; threads){
t.join();
}
// インクリメント結果を表示
writeln(sd.value);
}
|
multi_thread.d の実行結果は:
[cactus:~/code_d/d_tuts]% ./multi_thread
450
また, 排他制御に用いる mutex オブジェクトを指定することもできる.
multi_thread2.d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import std.stdio;
import core.thread;
class ShareData{
private int v;
public void increase(){
synchronized(this){
int a = v;
foreach(i; 0..10){
v = v + i;
}
}
}
public int value() const{
return v;
}
}
class IncrementThread : Thread{
private ShareData sd;
public this(ShareData sd){
this.sd = sd;
super(&f);
}
private void f(){
sd.increase();
}
}
void main(){
// 全部のスレッドで共有するデータ
auto sd = new ShareData;
// 10 個のスレッドを次々に作って実行開始
Thread[] threads;
foreach(i; 0..10){
auto t = new IncrementThread(sd);
threads ~= t;
t.start();
}
foreach(t; threads){
t.join();
}
// インクリメント結果を表示
writeln(sd.value);
}
|
multi_thread2.d の実行結果は:
[cactus:~/code_d/d_tuts]% ./multi_thread2
450
複数のスレッドから同じインスタンスにアクセスするとき, synchronized メンバ関数 を用いて排他制御を行える.
multi_thread3.d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import std.stdio;
import core.thread;
class ShareData{
private int v;
public synchronized void increase(){
int a = v;
foreach(i; 0..10){
v = v + i;
}
}
public int value() const{
return v;
}
}
class IncrementThread : Thread{
private ShareData sd;
public this(ShareData sd){
this.sd = sd;
super(&f);
}
private void f(){
sd.increase();
}
}
void main(){
// 全部のスレッドで共有するデータ
auto sd = new ShareData;
// 10 個のスレッドを次々に作って実行開始
Thread[] threads;
foreach(i; 0..10){
auto t = new IncrementThread(sd);
threads ~= t;
t.start();
}
foreach(t; threads){
t.join();
}
// インクリメント結果を表示
writeln(sd.value);
}
|
multi_thread3.d の実行結果は:
[cactus:~/code_d/d_tuts]% dmd -w multi_thread3.d
multi_thread3.d(24): Error: function multi_thread3.ShareData.increase () shared is not callable using argument types ()