2017-02-22 5 views
0

Я пытаюсь использовать анонимные каналы для связи с порожденным подпроцессом через их stdin и stdout, аналогичные this example. Пока что так хорошо - я общаюсь с ним через WriteFile(), и я читаю данные из него через PeekNamedPipe(), а затем ReadFile(). Жизнь хороша.Win32: анонимные унаследованные каналы не закрываются на выходе подпроцесса

Однако, я сталкиваюсь с чем-то неприятным - когда подпроцесс неожиданно закрывается, вызов родительского процесса в WriteFile() никогда не возвращает какое-либо состояние отказа, указывающее, что канал закрыт, и мой родительский процесс с радостью продолжает прерывать вдоль записи данных, пока я не переполним внутренний буфер трубы и не заблокирую его навсегда.

Мой код настройки выглядит следующим образом:

// Set up pipes 
SECURITY_ATTRIBUTES sec_attrs; 
memset(&sec_attrs, 0, sizeof(SECURITY_ATTRIBUTES)); 
sec_attrs.nLength = sizeof(SECURITY_ATTRIBUTES); 
sec_attrs.bInheritHandle = TRUE; 
sec_attrs.lpSecurityDescriptor = NULL; 

if (!CreatePipe(&midi_process_in_reader, &midi_process_in_writer, &sec_attrs, 0)) 
{ 
    DEBUGOUT("Could not initialize midiproc stdin"); 
    return false; 
} 

if (!SetHandleInformation(midi_process_in_writer, HANDLE_FLAG_INHERIT, 0)) 
{ 
    DEBUGOUT("Could not disinherit midiproc stdin"); 
    return false; 
} 

if (!CreatePipe(&midi_process_out_reader, &midi_process_out_writer, &sec_attrs, 0)) 
{ 
    DEBUGOUT("Could not initialize midiproc stdout/stderr"); 
    return false; 
} 

if (!SetHandleInformation(midi_process_out_reader, HANDLE_FLAG_INHERIT, 0)) 
{ 
    DEBUGOUT("Could not disinherit midiproc stdin"); 
    return false; 
} 

// Launch the subprocess 
PROCESS_INFORMATION proc_info; 
memset(&proc_info, 0, sizeof(proc_info)); 

STARTUPINFO startup_info; 
memset(&startup_info, 0, sizeof(startup_info)); 
startup_info.cb = sizeof(startup_info); 
startup_info.hStdInput = midi_process_in_reader; 
startup_info.hStdOutput = midi_process_out_writer; 
startup_info.dwFlags = STARTF_USESTDHANDLES; 

BOOL ok = CreateProcess(TEXT(module), TEXT(cmdline), NULL, NULL, TRUE, 
    CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &proc_info); 

Единственное различие, которое я вижу между примером и мой код является то, что я не подключить STDERR - Я хочу, чтобы держать его вокруг для отладки fprintf ,

Возможно, в конечном итоге мне понадобится какое-то сообщение «heartbeat», потому что подпроцесс может стать зомби и быть полностью живым и держать свои ручки открытыми, но никогда не считывать stdin, что клин вещи по-другому. Тем не менее, я хочу убедиться, что у меня не хватает чего-то в моем понимании анонимных труб в Windows.

ответ

7

Необходимо позвонить midi_process_in_reader и midi_process_out_writer после звонка CreateProcess(). Ваша проблема не в том, что «унаследованные каналы не закрываются на выходе подпроцесса», потому что вы забыли закрыть трубы в своем собственном процессе.

Смежные вопросы