2015-07-19 73 views
0

我想從一個分叉Python進程的父寫一些記錄的過程,所以我用一管爲:重定向分叉蟒蛇過程的輸出管道

rpipe, wpipe = os.pipe() 

pid = os.fork() 
if pid == -1: 
    raise TestError("Failed to fork() in prepare_test_dir") 

if pid == 0: 
    # Child -- do the copy, print log to pipe and exit 
    try: 
     os.close(rpipe) 
     os.dup2(wpipe, sys.stdout.fileno()) 
     os.dup2(wpipe, sys.stderr.fileno()) 
     os.close(wpipe) 

     self._prepare_test_dir(test) 

     sys.stdout.write(self.copy_log) 
    finally: 
     os._exit(1) 

os.close(wpipe) 

_, status = os.waitpid(pid, 0) 

# XXX: if copy_log is larger than PIPE_BUF (4-8k), everything 
# then is going badly 
outf = os.fdopen(rpipe) 
self.copy_log = outf.read() 

return os.WEXITSTATUS(status) 

它不工作,沒有什麼出現在self.copy_log。我也試圖明確建設標準輸出對象與fdopen

sys.stdout = os.fdopen(wpipe, 'w') 

不是工作壓力太大。但是,如果我把printdup2前:

if pid == 0: 
    try: 
     print 'HELLO' 
     os.close(rpipe) 
     os.dup2(wpipe, sys.stdout.fileno()) 
     os.dup2(wpipe, sys.stderr.fileno()) 
     ... 

複製日誌被成功傳遞到家長和「HELLO」打印到控制終端。我假設print以某種方式影響sys.stdout(與懶惰初始化或其他)。有任何想法嗎?

我在各種Linux平臺上使用Python 2.6和2.7。

+0

你正在做硬盤的方式,使用[模塊子(https://docs.python.org/2/library/subprocess.html )。 – msw

+0

我知道'subprocess',但我必須使用fork。不幸的是,只能保證fds是關閉的。此外,'fork()'不共享任何內容,它執行所有可寫段上的寫時複製。 – myaut

回答

1

該問題似乎不在pipe/dup2相關代碼中,而是os._exit。這是殺死python解釋器的殘酷方法(但對於分叉進程可以,因此它不會觸及「共享」對象),但會導致stdoutstderr不會被刷新,並且數據會丟失。

我的孩子來到了下面的代碼:

try: 
    os.close(rpipe) 
    os.dup2(wpipe, sys.stdout.fileno()) 
    os.dup2(wpipe, sys.stderr.fileno()) 
    os.close(wpipe) 

    print 'aaaaaaaaa' 
except: 
    traceback.print_exc(20, sys.stderr) 
finally: 
    sys.stdout.flush() 
    sys.stderr.flush() 
    os._exit(1)