2012-07-03 31 views
3

我使用子進程在python中產生進程,並且想要使用管道從程序中讀取輸出。 C++程序似乎並沒有關閉管道,即使明確告訴它關閉。Python和C++之間的管道不會關閉

#include <cstdlib> 
#include <ext/stdio_filebuf.h> 
#include <iostream> 

int main(int argc, char **argv) { 
    int fd = atoi(argv[1]); 
    __gnu_cxx::stdio_filebuf<char> buffer(fd, std::ios::out); 
    std::ostream stream(&buffer); 
    stream << "Hello World" << std::endl; 
    buffer.close(); 
    return 0; 
} 

我調用該小程序與此蟒片段:

import os                       
import subprocess                     

read, write = os.pipe()                   
proc = subprocess.Popen(["./dummy", str(write)])             
data = os.fdopen(read, "r").read()                 
print data                       

讀()方法不返回,因爲FD未關閉。在python中打開和關閉寫入fd可解決問題。但對我來說,這似乎是一個詭計。有沒有辦法在我的C++過程中關閉fd?

非常感謝!

回答

5

產卵Linux上的子進程(所有的POSIX操作系統,真的)通常是通過fork和0123完成。在fork之後,兩個進程都打開文件。 C++進程關閉它,但該文件保持打開狀態,直到父進程關閉fd。這對於使用fork的代碼來說是正常的,並且通常通過圍繞fork的包裝來處理。請閱讀man頁面pipe。我猜python無法知道哪些文件正在傳遞給孩子,因此不知道要在父對子進程中關閉什麼。

+0

有趣。意味着在構建「Popen」對象後關閉文件描述符? – krlmlr

+0

@ user946850:請參閱http://linux.die.net/man/2/pipe –

+4

上的示例代碼請參閱Python文檔中的示例:http://docs.python.org/library/subprocess.html #replacement-shell-pipeline。 「啓動p2後,p1.stdout.close()調用非常重要,以便p1在p1之前退出時接收SIGPIPE。」這意味着,是的,請關閉Python進程中的句柄。 – krlmlr

3

POSIX文件描述符是進程本地的。來自Python工具的文件描述符 write在C++過程中無效。

也許最簡單的方法是將有C++程序的輸出寫到stdout(如cout <<),和Python的呼叫使用stdout=PIPE和閱讀proc.stdoutPopen(或使用proc.communicate()而不是使用fdopen。這應該工作在Windows,太。

對於傳遞文件描述符作爲命令行參數,請參閱Ben Voigt's answer

+0

我不記得條件是什麼,但可以繼承文件描述符。 –

相關問題