非同期のプロセス間通信(パイプ)で全データ受信する
こんにちは。
非同期のプロセス間通信(パイプ)で詰まっています。
環境はWindowsで処理系はC++(Win32)です。
スレッドを用意して、
hPipe = ::CreateFile( L"\\\\.\\pipe\\pipename", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ) ;
で作成し、OVERLAPPED構造体を
//
ZeroMemory( &so, sizeof( OVERLAPPED )) ;
sOverlapped.hEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL ) ;
として、
const size_t bufsize = 16 ;
BYTE buffer[ uBufSize ] ;
DWORD dwNumberOfBytesRead ;
bRet = ::ReadFile( hPipe, buffer, bufsize, &dwNumberOfBytesRead, &so ) ;
で読み込みをしています。ReadFile関数はすぐ戻りbRetはFALSEで返ってくるため、GetLastErrorを調べて、
switch( ::GetLastError())
{
case ERROR_IO_PENDING :
bRet = ::GetOverlappedResult( hPipe, &so, &dwNumberOfBytesRead, FALSE ) ;
break ;
}
としてWaitForMultipleObjectsでsOverlapped.hEventがシグナル状態になったら取得したデータの処理をしています。
シグナル状態になるならないに関わらず、上記のReadFileとGetOverlappedResultはループでぐるぐる回しています。
上記の状態で短いデータならよかったのですが、上記のReadFileで読み込み最大サイズの16バイトを超えてしまとうと、
残りの部分のみしか取得できませんでした。
0123456789ABCDEFabcdefg
というデータを受信しようとしたとき、後半のabcdefgだけしか取得できませんでした。
すべてのデータを正しく取得するにはどのようにしたらよいのでしょうか?
お礼
そうそうの回答ありがとうございます。原文では「プロセスグループはシェルのパイプでつながれたプロセス群で、ジョブに対応します。」となっていました。 確かに内部的にはパイプはファイルと同じように、マウントできないpipfsファイルシステム下のinodeベーの読み書き。と認識しております。notnotさんの仰るようにここはパイプラインのことではと思っています。
補足
先にアップしてからふと思ったのですが、パイプラインは一方のプロセスのファイルディスクリプタ0の標準入力を、片方のファイルディスクリプタ1に、ファイルディスクリプタ1の標準出力を片方のファイルディスクリプタ0に繋ぎ変えて、そして内部的には通常のパイプと同じ処理をしているのではと。 そうなると、プロセスグループである必要がない。(プロセスグループはただタスク構造体のtgidというメンバーにプロセスリーダとなる親プロセスIDを設定しとそのリストを作っているだけ、大した処理はしてないようです。)そうなると、パイプラインを形成するのにプロセスグループが必要というのでなく、もし片方のプロセスにエラーが発生してフリーズしてしまえば、一方のプロセスの入出力ができなくなってしまい、そのような事態をさけるために、一方がアボートすれば他方のプロセスもアボートするようにするためでは。と思ったしだいなのですが・・・。どのようなものでしょうか?