24

簡単にするために、これは NamedPipe SERVER が NamedPipe CLIENT がパイプに書き込むのを待っている状況です (WriteFile() を使用)。

ブロックしている Windows API は ReadFile() です。

サーバーは、ブロッキングを有効にして同期パイプ (オーバーラップ I/O なし) を作成しました

クライアントが接続され、サーバーがデータを待機しています。

通常の流れでは、クライアントが何らかのデータを送信し、サーバーがそれを処理してから ReadFile() に戻り、次のデータのチャンクを待ちます。

その間、イベントが発生し (ユーザー入力など)、NamedPipe SERVER は他のコードを実行する必要がありますが、ReadFile() がブロックされている間は実行できません。

この時点で、NamedPipe Client は私のアプリケーションではないので、私はそれを制御できないことに言及する必要があります。サーバーのブロックを解除するために数バイトを送信することはできません。ただそこに座ってデータを送信しません。私はクライアントの実装を制御できないため、その側で何も変更することはできません。

1 つの解決策は、すべての ReadFile() 操作が実行される別のスレッドを作成することです。そうすれば、イベントが発生したときにコードを処理できます。これに関する問題は、イベントにも別のスレッドが必要であるため、このサーバーのインスタンスごとに 2 つのスレッドを追加することです。これはスケーラブルである必要があるため、望ましくありません。

呼び出してみた別のスレッドから

 DisconnectNamedPipe()

 CloseHandle()

どちらも戻りません (クライアントがパイプに書き込むまで)。

次の理由により、同じパイプに接続して数バイトを書き込むことができません。

「名前付きパイプのすべてのインスタンスは同じパイプ名を共有しますが、各インスタンスには独自のバッファーとハンドルがあり、クライアント/サーバー通信用の個別のコンジットを提供します。」

http://msdn.microsoft.com/en-us/library/aa365590.aspx

私はそれを偽造する方法が必要です.64,000ドルの質問は次のとおりです。

ReadFile() のブロックを解除するにはどうすればよいですか?

4

7 に答える 7

18

ReadFileの前にこれを試してください:

BOOL WINAPI PeekNamedPipe(
  __in       HANDLE hNamedPipe,
  __out_opt  LPVOID lpBuffer,
  __in       DWORD nBufferSize,
  __out_opt  LPDWORD lpBytesRead,
  __out_opt  LPDWORD lpTotalBytesAvail,
  __out_opt  LPDWORD lpBytesLeftThisMessage
);

if(TotalBytesAvail > 0)
  ReadFile(....);

-AV-

于 2009-08-04T12:51:05.873 に答える
6

CancelSynchronousIo を見てみましょう

指定されたスレッドによって発行された保留中の同期 I/O 操作をキャンセル済みとしてマークします。

CancelIo/CancelIoEx:

保留中の非同期 I/O 操作をすべてキャンセルするには、次のいずれかを使用します。

CancelIo — この関数は、指定されたファイル ハンドルに対して呼び出しスレッドによって発行された操作のみをキャンセルします。

CancelIoEx — この関数は、指定されたファイル ハンドルに対してスレッドによって発行されたすべての操作をキャンセルします。

于 2009-02-27T03:01:42.433 に答える
3

マイク、

同期 ReadFile をキャンセルすることはできません。ただし、非同期 (オーバーラップ) 操作に切り替えることはできます。これにより、非常にスケーラブルなアーキテクチャを実装できます。

可能なアルゴリズム(単なるアイデア):

  • 新しいクライアントごとに ReadFile を呼び出す
  • ハンドルがオーバーラップしている WaitForMultipleObjects.hEvent + カスタム イベント
  • 通知されたイベントを繰り返し処理し、スレッド プールからのスレッドによる実行のためにそれらをスケジュールします。

このようにして、接続を受信して​​データを読み取るためのスレッドを少数にすることができますが、実際のデータ処理はスレッド プールで行うことができます。

于 2009-02-27T01:46:31.647 に答える
2

これに関する問題は、イベントにも別のスレッドが必要であるため、このサーバーのインスタンスごとに 2 つのスレッドを追加することです。これはスケーラブルである必要があるため、望ましくありません。

私のキャリアの中で、「より多くのスレッド」 == 「スケーラビリティが低い」と気付いたことはありません。これらの「サーバー」インスタンスはいくつありますか?

通常、操作がブロックされ、操作がブロックされている間にシステムが応答する必要がある場合は、別のスレッドで操作を実行する必要があります。

于 2009-02-27T01:14:31.380 に答える
1

非同期 I/O 操作は、I/O 完了ポートを使用する場合、スレッドをブロックする必要はありません。参照: http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx

于 2009-06-04T03:26:16.153 に答える
1

クライアントがサーバーのインバウンドパイプに接続しようとしている間、サーバーのアウトバウンドパイプが接続を待って開いたままになっています(これはもう存在しません)...あなたがする必要があるのは、ループするためにアウトバウンドパイプをフラッシュすることですインバウンドに戻ります。ファイルを読み取ることにより、クライアント側でフラッシュアウトできます (そこに「ハンドシェイク」があるため、接続確立をループすることを忘れないでください。最初は機能しません)。

于 2017-03-23T18:57:29.460 に答える