2017-02-22 86 views
0

我一直在試圖使用匿名管道通過它們的stdin和stdout與產生的子進程通信,類似於this example。到目前爲止,這麼好 - 我通過WriteFile()與它通信,並通過PeekNamedPipe()從ReadFile()中讀取數據。生活很好。但是,我遇到了一些令人不快的事情 - 當子進程意外關閉時,對WriteFile()的父進程調用似乎永遠不會返回任何類型的失敗狀態,表示管道已關閉,並且我的父進程繼續愉快地繼續進行chugging一直寫數據,直到我溢出管道的內部緩衝區並永遠阻塞。Win32:匿名繼承管道在子進程退出時不關閉

我的設置代碼如下所示:

// 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); 

,我可以的例子,我的代碼之間看到的唯一區別是,我不掛鉤標準錯誤 - 我想圍繞保持它fprintf中調試。

從長遠來看,我可能需要帶着某種「心跳」信息,因爲子進程可能會變成殭屍,並且完全活着並且保持其手柄處於打開狀態,但從未讀取stdin,以不同的方式楔入事物。但是,我想確保我不會在Windows中理解匿名管道時錯過某些東西。

回答

7

致電CreateProcess()後,您必須關閉midi_process_in_readermidi_process_out_writer。你的問題不是因爲「繼承的管道不能在子流程退出時關閉」,這是因爲你忘記關閉你自己進程中的管道。