2016-06-30 90 views
0

我有一個使用子進程調用另一個腳本的腳本(Python)。父腳本同時寫入控制檯和日誌文件(我使用this question的接受答案中的代碼拆分輸出),但子進程的打印語句只是stdout,而不是日誌文件。同時寫入子進程和父進程的文件

我知道這是爲什麼:子進程有stdout設置爲正常的標準輸出,而不是父進程具有的特殊tee對象。我嘗試將tee對象作爲參數傳遞給子進程,但我學會了難以將對象作爲參數傳遞給子進程的難題。我的備份計劃是傳遞要寫入的文件的路徑字符串,然後讓子進程使用同一個文件創建自己的TEE對象。

我的問題是,如果兩個進程都在同一時間寫入同一個文件,輸出是否會混亂?我在父進程中使用open(「file」,'w'),並且這首先被調用,並且在子進程中使用open(「file」,'a')。假設文件應該以正確的順序包含打印語句的輸出,因爲向文件添加'a'意味着這些行總是被添加到當前文件的結尾,不是嗎?還是有規則打開一個文件,防止它被同時打開的兩個進程?

POST_TEST:做一些測試自己以後,我發現: - 您才能打開(「文件」,「W」)連續 多次 - 你才能打開(「文件」, 'w'),然後打開(「file」,'a') - 在第一種情況下,子進程完全覆蓋文件。 - 在第二種情況下,順序不正確,某些輸出似乎丟失。

我的新問題是,我應該用什麼替代解決方案同時從父進程和子進程寫入文件,而不會導致順序錯亂或重疊?

+0

Google「互斥體」。互斥鎖是資源上的MUTually EXCLUSIVE鎖,可避免兩個進程使用相同資源時發生衝突。 –

+0

http://stackoverflow.com/questions/489861/locking-a-file-in-python –

+1

以「a」模式打開的進程將始終寫入文件末尾。但是以'w'模式打開的那個不會。您需要以'a'模式打開它們。 – Barmar

回答

0

謝謝Bamar的建議:使用「a」作爲第一個和第二個open()作品。如果您需要爲已存在的文件執行此操作,則可以使用file.truncate()在追加文件之前清空該文件。

+0

如果文件以「a」模式打開,則不能保證所有寫入都在最後的所有系統上。不保證larges write()是原子的(來自多個進程的輸出可能交錯)。 – jfs

0

打開文件'w'模式截斷文件(as documented)。在'a'模式下打開文件可能會在某些系統上工作。 POSIX says for O_APPEND flag

如果設置,則應在每次寫入之前將文件偏移設置爲文件末尾。

write()s that are larger than PIPE_BUF may interleave

POSIX.1-2008不說超過{} PIPE_BUF字節更多的寫請求是否爲原子,但需要{} PIPE_BUF或更少的字節寫入應是原子的。


問:我應該用什麼替代解決方案寫入從同時父和子進程的文件時,沒有得到線出故障或重疊?

打開使用線緩衝模式(1),在每一行的末尾沖洗內部緩衝器中的文件 - 它應該保留線的近似相對順序。如果行數小於PIPE_BUF(我係統上的4096字節),那麼它們不應該「重疊」。


子進程可以將數據寫入到它的標準輸出和您的父母Python進程可以把它寫在你喜歡的任何順序的文件。見how teed_call() function is implemented

+0

我不介意downvote,但我將不勝感激解釋,可以讓答案更好。 – jfs

+0

我討厭它,當人們downvote不說爲什麼他們這樣做 –