从管道读取时Win32 ReadFile挂起

Mat*_*att 6 winapi hang readfile

我正在创建一个子进程,并读取其输出.当子进程创建output(cmd /c echo Hello World)时,我的代码工作正常,但是如果进程没有创建output(),则ReadFile将挂起cmd /c echo Hello World > output.txt.我只是在流程终止后才开始阅读.

我做错了什么吗?无论如何使用同步模式执行此操作,还是必须使用异步模式?所有这一切都发生在一个单独的线程中,所以我不认为异步模式会给我任何好处,除非它是让这个工作的唯一方法.非常感谢!

saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
saAttr.bInheritHandle = TRUE; 
saAttr.lpSecurityDescriptor = NULL; 

CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0);
SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0);

memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION));
memset(&siStartInfo, 0, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO); 
siStartInfo.hStdError = g_hChildStd_OUT_Wr;
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
CreateProcess(NULL, commandWideString, NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo);

while(1)
{
    GetExitCodeProcess(piProcInfo.hProcess, &processExitCode);
    if(processExitCode != STILL_ACTIVE)
        break;
    else
        Sleep(1);
}

*output = (char *)calloc(32, sizeof(char));
processOutputSize = 0;
while(1)
{
    bSuccess = ReadFile( g_hChildStd_OUT_Rd, processOutputTemp, 32, &dwRead, NULL);
    if(!bSuccess || !dwRead)
        break;
    memcpy(*output + processOutputSize, processOutputTemp, dwRead);
    processOutputSize += dwRead;
    if(dwRead == 32)
        *output = (char *)realloc(*output, processOutputSize + 32);
    else
    {
        memset(*output + processOutputSize, 0, 1);
        break;
    }
}
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
CloseHandle(g_hChildStd_OUT_Rd);
CloseHandle(g_hChildStd_OUT_Wr);
Run Code Online (Sandbox Code Playgroud)

Mic*_*čný 9

在读取输出管道之前,应该关闭输出管道的写入端,正如@Marcus在评论中建议的那样.

CloseHandle(g_hChildStd_OUT_Wr);

对我来说,这才是真正的答案.

  • 如果我想要子进程和父进程之间持续通信怎么办?例如通过管道与鳕鱼 uci 交谈。 (3认同)

wim*_*ica 6

您将进程的输出重定向到管道,启动进程,等待它退出,然后读取输出。

问题在于 Windows 仅缓冲有限数量的数据。所以你必须在进程仍在运行时读取管道,否则进程将被阻塞,因为它无法再向管道写入任何数据。