Idleになったスレッドはイベント待ちにする件
2chのコンピューター将棋スレでいただいた質問にお答えします。
スレッドの生成に時間がかかる、というのはわかるが
スレッドを待たせるのにCPU時間を使う理由がわかんね
Idleになったスレッドは(終了せずに)イベント待ちにして、
必要なとき外からSetEvent()して起こす、じゃいかんの?
まず、スレッドを待たせるのにCPU時間を使っていた理由ですが、Bonanzaではスレッドの待機にWindows系ではSleep(0)を用いており(thread.cのwait_work関数)、Sleep(0) → 仕事があるかどうかを見る → Sleep(0)→… というspinlock構造になっています。
Bonanzaでは自分の手番が終わったときにスレッドはいったん終了させているのですが、私はスレッド起動に要する時間が惜しかったのでそのまま待機させていました。そうするとSleep(0)をspinlockで繰り返すためにCPU時間をいくぶん消費していたということです。
このときの(相手番での)待ちかたとしてイベント待ちにするのはそれが普通だと私は思います。
しかしSleep(0)までイベント待ち(WaitForSingleObject)に置き換えた場合、この待ち状態からの復帰にかかる時間はおそらくSleep(0)からの復帰時間より長いと思うので[要検証]、Sleep(0)までは置き換えられません。
また、スレッド分だけイベントを作成して、スレッド数の変更を指定されたときにまたイベントを解体して作成しなおしたりするコードを書くのが面倒でしたので、私は
if ( is_tlp_sleep ) Sleep(1);
とstaticなbooleanなフラグをひとつ用意してSleep(1)を使って解決しました。 あまりお行儀のいいコードではありませんが。