2011-05-07 36 views
9

http://docs.python.org/library/functions.html#open爲什麼要緩衝子進程的標準輸出(重定向到無緩衝文件)?

可選BUFSIZE參數 指定文件的所需的緩衝區 大小:0表示無緩衝,1表示緩衝線 ,任何其他正值 裝置使用(大約) 該大小的緩衝器。負bufsize意味着 使用系統默認值,即 通常行緩衝tty設備 併爲其他文件完全緩衝。如果省略了 ,則使用系統默認值。

我將0作爲bufsize傳遞給下方,但未使用flush()當我運行main_process時沒有輸出寫入文件。
是什麼原因?

# --------------------------------- sub_process.py 
import sys 
import time 

if __name__ == '__main__': 
    print 'printed from redirect.py' 
    # why is the following flush() needed? 'std-output' is (?) unbuffered... 
    sys.stdout.flush() 
    time.sleep(6) 


# --------------------------------- main_process.py 
import subprocess 
import time 

if __name__ == '__main__': 
    p = subprocess.Popen(
     ['python', 'sub_process.py'], 
     stdout=open('std-output', 'w', 0)) 
    time.sleep(3) 
    p.terminate() 
+0

+1,我花了大約30分鐘試圖找出爲什麼'sys.stdout' - >'subprocess.PIPE'幾天前沒有工作。 'flush()'是答案,但我們爲什麼需要它? – 2011-05-07 17:21:40

回答

5

擴展馬格努斯斯科格溶液(+1順便說一下:)):

嗯,基本上什麼情況是,當子將分叉一個新的進程,它將使用os.dup2(看看subprocess.Popen._execute_child)複製stdout參數到新的子進程標準輸出(fileno = 1),這將保持未緩衝狀態(如dup2所做的那樣),直到現在一切都很好,但是當python默認啓動時(在子進程中),如果python沒有看到-u標誌會將stdout的緩衝區設置爲行緩衝區(請參閱main python function。),它將覆蓋您之前設置的緩衝標誌。

希望這解釋更多的你看到的行爲。

+0

+1 back :)感謝您澄清這一點。 – ralphtheninja 2011-05-08 10:13:13

6

使用Python -u標誌,如:

if __name__ == '__main__': 
    p = subprocess.Popen(
     ['python', '-u', 'sub_process.py'], 
     stdout=open('std-output', 'w')) 
    time.sleep(3) 
    p.terminate() 
+0

這工作,謝謝。雖然,我仍然想知道爲什麼它需要? – 2011-05-07 17:15:44

+0

我的猜測是,如果你用file.write()直接寫入文件,它將被緩衝,但事實上你正在間接地寫它,因爲python會在你的文件發送數據之前緩衝你的打印命令,因此你需要-u標誌來告訴python不緩衝打印命令。 – ralphtheninja 2011-05-07 17:25:16

+0

'sys.stdout.write('from redirect.py'打印)'給出了與打印相同的結果 - 沒有任何東西被寫入文件 – 2011-05-07 17:45:01