Win32 ReadFile se bloque lors de la lecture de la pipe
Je suis entrain de créer un processus fils, et la lecture de sa sortie. Mon code fonctionne très bien lorsque le processus de l'enfant crée de sortie (cmd /c echo Hello World
), cependant ReadFile va se bloquer si le processus ne crée pas de sortie (cmd /c echo Hello World > output.txt
). Je ne fais que de la lecture après le processus est terminé.
Je fais quelque chose de mal? Est-il de toute façon pour ce faire avec le mode synchrone, ou dois-je utiliser le mode asynchrone? Tout cela se passe dans un autre thread, donc je ne pense pas que le mode asynchrone offrirait aucun avantage pour moi, sauf si c'est la seule façon d'obtenir que cela fonctionne. Merci beaucoup!
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);
- J'ai eu un blocage de readfile, et généralement c'est un unclosed gérer ce qui provoque la lecture de bloc. Après que votre enfant quitte que nous pouvons fermer votre poignée à l'écriture, à la fin de la pipe. Cela vous aide?
- il aide. Si le processus de renvoie de sortie ReadFile va réussir en tant que normale. Si le processus n'a pas de retour de sortie, ReadFile va échouer et GetLastError() retournera 109 code d'Erreur " Broken Pipe. Est-ce un comportement normal? Merci.
Vous devez vous connecter pour publier un commentaire.
Vous rediriger la sortie du processus à un tuyau, démarrer le processus, attendre jusqu'à ce qu'il quitte, et ensuite de lire la sortie.
Le problème est que windows tampons seulement une quantité limitée de données. Vous devez lire la pipe alors que le processus est toujours en cours d'exécution, sinon le processus sera bloqué car il ne peut pas écrire plus de données à la pipe.
Vous devez fermer la fin d'écriture de la sortie du tube avant de vous lire, comme @Marcus suggéré dans les commentaires.
CloseHandle(g_hChildStd_OUT_Wr);
Pour moi, c'est la vraie réponse.
Vous pouvez utiliser PeekNamedPipe dans une boucle comme ceci: