2017-05-29 96 views
2

我試圖用一個字符串調用一個進程到它的stdin,用boost-1.64.0。 當前的代碼是:關閉boost :: process子進程的stdin

bp::opstream inStream ; 
    bp::ipstream outStream; 
    bp::ipstream errStream; 

    bp::child child(
    command, // the command line 
    bp::shell, 
    bp::std_out > outStream, 
    bp::std_err > errStream, 
    bp::std_in < inStream); 


    // read the outStream/errStream in threads 

    child.wait(); 

的問題是,孩子可執行文件正在等待它的標準輸入EOF。這裏child.wait()無限期懸掛...

我試圖使用asio :: buffer,std_in.close(),但是沒有運氣。 我發現的唯一破解是刪除()inStream ...並且這不是很可靠。

我應該如何「通知」子進程並關閉它的stdin和新的boost ::進程庫?

謝謝!

+0

你是什麼意思,_「delete()inStream」_?這對我來說沒有多大意義。 – sehe

回答

2

我試圖使用ASIO ::緩衝區,std_in.close()

這工作。當然,只有將它傳遞給啓動函數(bp :: child構造函數,bp :: system等)纔有效。

如果您需要傳遞數據,然後關閉它,只需關閉相關的文件描述符即可。我做這樣的事情:

boost::asio::async_write(input, bp::buffer(_stdin_data), [&input](auto ec, auto bytes_written){ 
    if (ec) { 
     logger.log(LOG_WARNING) << "Standard input rejected: " << ec.message() << " after " << bytes_written << " bytes written"; 
    } 
    may_fail([&] { input.close(); }); 
}); 

哪裏input

bp::async_pipe input(ios); 

此外,檢查過程中實際上並沒有停留在發送輸出!如果你沒有使用輸出,它會緩衝並等待緩衝區已滿。

+0

你節省了我的一週。我想may_fail是異常的自定義處理程序,所以我直接調用input.close()。你也必須調用ios.run():) – Salamandar

+0

是!對不起,這次複製不完整的代碼:(http://paste.ubuntu.com/24701992/ – sehe

1

完成寫入後,通過調用inStream.close();來關閉管道。您也可以在啓動​​時關閉它。

asio解決方案當然也有效,避免了死鎖的危險。