先日の日記の続き。
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(違