今日の役に立たない一言 - Today’s Trifle! -

古い記事ではさまざまなテーマを書いていますが、2007年以降はプログラミング関連の話がほとんどです。

名前付きパイプでさらに悩む

名前付きパイプを使ってプロセス間通信をするアプリケーションの話の続き。
昨日の日記で書いたように、アプリケーションは受信スレッドを作成してそこで接続や受信を待つようにするしかない。
もちろん受信スレッドが待つべきイベントは、接続やデータ受信だけではない。アプリケーション自身が終了する際にはリソースを解放する必要がある。アプリケーションを終了させるため、接続や受信のイベントを待っているスレッドに対しては割り込みをかけてブロック状態を解除する、というのが一般的なプログラミングだろう。
そういう場合には、WaitForSingleObject または WaitForMultipleObjects と言う Windows API を使うのが Windows プログラミングで定石。
さっそく名前付きパイプのハンドルと受信スレッド停止のイベントを指定して WaitForMultipleObjects した。が、ブロックされない。なぜか常にシグナル状態になっていて、まったくブロックされない。
MSDN で WaitForSingleObject を確認したところ、「名前付きパイプでの使用は推奨しない」とある。名前付きパイプをノンブロッキングモードで使ってはいけないそうだ。和訳が間違っているのかと思って、原文も読んでみたが、確かにそう書いてある。
どーすればいいんじゃぁ!
(ごそごそ)
回避方法が分かった。*1

  • 名前付きパイプはブロッキングモードで使う
  • ブロックを解除したいときは、名前付きパイプのハンドルをクローズする

というのがポイント。ハンドルをクローズすることでブロック状態の関数が異常終了する。
(ごそごそ)
と思ったらだめだった。笑い話のようだが、CloseHandle 関数がブロックされたままになってしまった。
と言うわけで、次の回避策として、自分で名前付きパイプに接続することで接続待ちのブロック状態を解除することにした。
うまくいった。(^^)

*1:M$社員が書いたソケット本でこの方法が紹介されているとのこと