...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

D言語で「Java言語で学ぶデザインパターン入門【マルチスレッド編】」を学ぶ

本を読みながらコードを書いていきたい.


Mutexは単にひとつのスレッドからしか実行できないようにするもの.
Conditionは明示的に通知をしてスレッド間で同期を取ることができるもの.
Conditionの方がMutexよりも細かい制御ができる.


コードが間違っていたので訂正.
wait/notifyを呼ぶときにはロックを取得していなければならない.
これはどういうことかと言うと,Conditionに渡したMutex mをロックするためにsynchronized (m)ブロックを作って,その中でwait/notifyを呼ばなければならないということ.


また,notifyを呼び出しても,waitしているスレッドがすぐに m のロックを再取得して処理を継続するわけではない.
notifyを呼び出したときには「notify を呼び出したスレッド」がmをロックしているので,wait側は m をロックすることができないから.
notify側が m のロックを解放するタイミングをちゃんと用意してあげること.

import std.stdio;
import core.thread;
import core.sync.mutex;
import core.sync.condition;

// 別のスレッドでカウントを3回表示するまで待ってから終了する
void main()
{
	auto m = new Mutex; // 排他処理用のmutexを作って
	auto c = new Condition(m); // conditionに渡す
	void f()// スレッドのエントリポイント
	{
		foreach (i; 0..3)
		{
			writeln("\t", i); // カウントを3回表示して
		}
		synchronized (m) // cじゃなくてmのロックを取る
			c.notify(); // mに対するwaitを起こす
		writeln("\tend"); // このスレッドを終了
	}
	auto t = new Thread(&f); // スレッドを作成
	t.start(); // スレッド開始
	writeln("0");
	synchronized (m) // cじゃなくてmのロックを取る
		c.wait(); // mに対してnotifyが呼ばれるまで停止する
	writeln("END");
}

本来これだけの処理ならばメインスレッドで t.join() を呼び出してスレッドの終了を待てば十分だろう.


マルチスレッドを勉強しながらなのでこれからも間違える可能性が高いでしょう.