12

2 つの子プロセスを作成し、継承されたパイプをそれぞれ待機し、出力をファイルに入れる単純なプログラム (C) があります。

2 つのパイプでの書き込み/読み取りサイクルの後、子プロセスが終了すると、ReadFile ブロックの呼び出しがパイプでデータを待機することを除いて、すべてが正常に機能します。私は次のパターンを使用します。

...
//create pipe1
CreatePipe(&hReadDup,&hWrite,&saAttr,0);
DuplicateHandle(GetCurrentProcess(),hReadDup,GetCurrentProcess(),&hRead,0,FALSE,DUPLICATE_SAME_ACCESS);
CloseHandle(hReadDup);


si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hWrite;   

CreateProcess(  NULL,
        const_cast<LPWSTR>(cmd2.c_str()), //the command to execute
        NULL,
        NULL,
        TRUE,
        0,
        NULL,
        NULL,
        &si, //si.
        &pi
    );

...
CloseHandle(hWrite); // EDIT: this was the operation not properly done!

while(cont){
    ...
    cont = ReadFile(hRead,buf,50, &actual,NULL);
    ...
}
... 

最後の呼び出し (子プロセスの終了後) ブロック。理由のアイデア (そうでない場合は、これをデバッグする方法)?

4

3 に答える 3

14

私は自分で解決策を見つけました(実際にはコーディングエラーでした)。パイプの親の書き込みハンドルを適切に閉じていなかった ( hWrite) ため、同期 ReadFile は子プロセスの終了を報告できませんでした。

誰かが同じ問題を抱えている場合は、そのパイプで I/O 操作を開始する前に、パイプの継承可能なハンドルを閉じていることを確認してください (MSDN の報告によると、再度見つけることができません)。

于 2012-06-02T13:53:55.547 に答える
7

ReadFile()同期モードで呼び出しています。パイプが開いている限り、次のReadFile()データを待ってブロックします。返されるプロセスとスレッド ハンドルを開いたままにしておくCreateProcess()と、子プロセスが完全に終了できなくなり、子側でパイプが閉じられない場合があります。読み取りループに入る前に、返されるハンドルをCreateProcess()閉じて、子プロセスが完全に終了したときにパイプが適切に閉じられるようにし、ReadFile()パイプから読み取れなくなったときにエラーを報告できるようにします。または、パイプでオーバーラップ I/O に切り替えて、ループの実行中WaitForSingleObject()または実行中に子プロセスを監視し、パイプの状態に関係なく子プロセスがいつ終了するかを検出できるようにします。GetExitCodeProcess()

于 2012-06-01T21:06:25.677 に答える