2016-07-09 6 views
0

私のパイプの1つが読み込まれるまでブロックする必要があります。ウィンドウ上のパイプのselectと同等

私はWaitForMultipleObjectsを試しましたが、ただパイプの1つにデータがあるとすぐに返します。パイプブロック上の次のReadFile。

私はデータが利用できるようになるまでブロックする必要があるため、PeekNamedPipeを使用することはできません。また、スリープのループでピークを検出すると、スリープにより反応が遅くなります。

このコードはクロスプラットフォームであり、私はfifoのfdのセットでSelectを使用して、選択したときに準備ができているものから読み取ることができるため、Linux上ですべてうまく動作しますが、窓に

多くの人が読んだり書いたりして重複した操作を使わなければならないと言ってきましたが、これはループしてすべてのパイプを試してみる必要はありませんか?

パイプの1つにデータがあるまでブロッキング操作がブロックされていませんか?

+3

"私はWaitForMultipleObjectsを試しました" - あなたの問題を解決しようとしたときに書いたコードが適切だと思うなら、あなたは正しいです。それはあなたの問題を再現する可能性のある最小限の、しかし理想的には完全な例として取り除かれています。 WaitForMultipleObjectsを間違って使用していることがわかっているため、その前提を否定するコードは掲載されていません。そして、はい、重複またはiocpは私がおそらくこれを行う方法です。 – WhozCraig

+0

@EJPいい神! 1993年は火の発明より前か? – user4581301

+0

もっと重大な点として、WaitForSingleObjectはWAIT_OBJECT_0 + nを返します.nはシグナルされた配列インデックスのインデックスです。ドキュメンテーションに明記されているので、実際に戻り値をチェックしていないので、 'WaitForSingleObject'の呼び出しは実際には' WAIT_FAILED'を返しています。実際に何をしているのかわからないので、これはビジネス上の推測として知られています。戻り値を正しくチェックし、エラーをきれいに処理するコードを書いているかもしれません。 – theB

答えて

2

私はWaitForMultipleObjectsを試しましたが、パイプの1つにデータがあるとすぐに返します。パイプブロック上の次のReadFile。

パイプはMSDNの待ちオブジェクトタイプのリストには記載されていないため、WaitFor...()ファシリティファミリのいずれにもパイプを渡すことはできません。

私は多くの人々はあなたが書き込み/読み取りと重複操作を使用する必要が言って見てきましたが、これは、ループに私を必要とし、一つ一つのパイプを試してみて、読んでいないでしょうか?

オーバーラップI/Oが問題の解決方法です。

パイプをオーバーラップモードで作成します。次に、あなたがいずれかをすることができます:

  1. CreateEvent()を経由してイベントオブジェクトを作成し、特定の読み出し動作のために使用OVERLAPPED構造に割り当てます。次に、複数のパイプ上で非同期操作ReadFile/Ex()を発行し、WaitForMultipleObject()を使用して、イベントオブジェクトの1つが通知されるまでイベントオブジェクトを待機させることができます。 WaitForMultipleObjects()の戻り値は、どのイベントが通知されたか、どのパイプが何らかのデータを読み込んだことを関連づけて通知します。

  2. の代わりにGetQueuedCompletionStatus/Ex()を使用すると、イベントオブジェクトを省略できます。 GetQueuedCompletionStatus/Ex()は、構造体が完了した具体的なOVERLAPPEDを教えてくれます(必要に応じて、hEventフィールドを使用してユーザー定義データを渡すことができます)。

これは、MSDNのドキュメントで覆われている:

Synchronous and Overlapped Pipe I/O

select()は、単一の呼び出しで複数の完了した操作を報告することができます。ただし、WaitForMultipleObjects()およびGetQueuedCompletionStatus()は、一度に完了した操作を1つしか報告できません。複数の操作が完了したかどうかを調べるには、それらをループで呼び出さなければなりません。一方、GetQueuedCompletionStatusEx()は、複数の完了した操作を一度に報告することができます。

1つのパイプにデータが入っているまでブロックされないブロック処理はありますか?

はい。上記を参照。

+0

素晴らしい、はるかに良い私はWaitForMultipleObjectsの戻り値が間違っている可能性があると言ったコメント。もともと私はPOSIXとwindowsパイプをラップしていて、重複を使用する方法を提供していなかったので、これは間違いなく痛いものになります。私はこの仕事をするために戻って多くを変えなければなりません。 もう一度ありがとう! – user6567423

-1

はい、オーバーラップI/Oを使用するのが最適です。すべてのパイプハンドルをI/O完了ポートにバインドすることができます(直接CreateIoCompletionPort()経由、間接的にはBindIoCompletionCallback()経由)。非同期読み取りの場合は、OVERLAPPEDから継承した構造体を作成し、パイプハンドルでReadFile/Ex()に渡します。各読み込みには、その構造体の割り当てられたインスタンスが必要です。次に、GetQueuedCompletionStatus()(またはバインドされたコールバック)を使用して、各読み取りが完了したことを検出できます。ループは必要ありません。

+3

私はここで文法を修正しようとしましたが、最後の '文章'は意味をなさない。もしあなたが、特にこのような質問に答えるつもりなら、それを提出する前にあなたの答えを校正してください。 (このような質問や一般的なWinAPIタグでは、あなたの答えを校正し、合理的に完了している限り、西の中で最速の銃である必要はありません) – theB

関連する問題