Win32, ReadFile desde el bloque de tuberías incluso después de que el hijo haya terminado

Tengo un progtwig simple (en C) que crea dos procesos secundarios, espera en un conducto heredado cada uno y coloca la salida en un archivo.

Todo funciona bien, excepto que después de un ciclo de lectura / escritura en la tubería dos, cuando finaliza el hijo, la llamada a ReadFile se bloquea, esperando datos en la tubería. Yo uso el siguiente patrón:

... //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(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); ... } ... 

El bloque de la última llamada (después de la salida del proceso hijo). ¿Idea de por qué (y, si no, cómo depurar esto)?

Descubrí la solución yo mismo (que en realidad fue un error de encoding). No estaba cerrando correctamente el controlador de escritura de la canalización del hWrite ( hWrite ), por lo que el ReadFile síncrono no pudo informarme de la finalización del proceso hijo.

Si alguien tiene el mismo problema, asegúrese de cerrar el controlador heredable de la tubería antes de iniciar la operación de E / S en esa tubería (ya que los informes de MSDN no se pudieron encontrar de nuevo).

Está llamando a ReadFile() en modo síncrono. Mientras el canal esté abierto, ReadFile() bloqueará la espera de más datos. Si deja abierto el proceso y los controles de subproceso que CreateProcess() devuelve, eso evitará que el proceso hijo se cierre por completo, por lo que es posible que la tubería no se cierre en el extremo hijo. Antes de ingresar a su ciclo de lectura, cierre los controladores que devuelve CreateProcess() , permitiendo que la tubería se cierre correctamente cuando el proceso hijo finalice por completo, y luego ReadFile() puede informarle un error cuando ya no pueda leer la tubería. . Alternativamente, cambie a la E / S superpuesta en la tubería para que pueda monitorear el proceso secundario con WaitForSingleObject() o GetExitCodeProcess() mientras se ejecuta el ciclo para que pueda detectar cuándo finaliza el proceso secundario independientemente del estado de la tubería.

En su caso todo bien, tuvo acceso a ambos procesos en la tubería. Sin embargo, si no lo hizo, o simplemente quiso interrumpir la llamada de ReadFile , entonces CancelSynchronousIo es su amigo: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363789(v=vs.85). aspx