Chiharu の日記

絵描き C/C++ プログラマーの日記です。

WaitForMuitipleObjects 〜POSIX スレッドでは?

先日の日記の続き。
Win32API のイベント処理に対応する POSIX スレッドの API は下記のようです。

Win32API POSIX 概要
CreateEvent pthread_cond_init 同期オブジェクトの初期化
CloseHandle pthread_cond_destroy 同期オブジェクトの解放
SetEvent pthread_cond_signal イベントの通知
WaitForSingleObject pthread_cond_wait イベントの通知待ち

API の詳細は他のサイトにたくさん書いてあるので割愛するとして。これでどうやって複数のイベントを同時に待てばいいんだろう…。
パラレル・フォースでは、ワーカースレッドのイベント待機は、アプリ終了時の応答性確保のため、ワーカースレッドの割り込み用イベントと待機対象イベントの 2 つを WaitForMultipleObjects API で待つようにしているのですが。んー。POSIX スレッドへの移植は、もうちょっと考える必要がありそう。

WaitForMultipleObjects を POSIX スレッドで実装

結局、pthread API を単純に使っただけでは WaitForMultipleObjects (以降 WFMO) 相当の動作を実現できなかったので、当該 API をエミュレーションするコードを実装しました。方針は下記のとおり。

  • WFMO 用に『共通イベント』を用意する
  • 各イベント クラスに『共通イベント』のリンク リストを実装
  • 各イベント クラスのシグナル メソッド実行時、自イベントだけでなく、リンク リストを辿って、自オブジェクトに関連付けられた全ての『共通イベント』をシグナル状態にする。
  • WFMO 時に下記を実施
    • 『共通イベント』を構築
    • 『共通イベント』を待機対象の全てのイベント クラスのリンク リストに追加
    • 各イベントを直接待機せず、『共通イベント』を待機する
    • 待機後、各イベントのシグナル状態を調べる
    • 先ほど登録した『共通イベント』を待機対象の全てのイベント クラスのリンク リストから削除
    • 『共通イベント』を破棄

という感じで実装してみたところ、ぼちぼちうまく動作しました。
―――が、この程度のことはすでに先人がいたようで、こちらにほぼ同等のコードが載っていましたとさ。んー。まぁ、試行錯誤したおかげで理解は進みましたが、遠回りした感がぬぐえませんでした。
何はともあれ、パラレル・フォースはこれで POSIX スレッド API に完全対応です。目指せ!脱 Win32API(違