我有一個可能長時間運行的程序,目前有4個進程,但可以配置更多。我已經使用python的logging
研究了logging from multiple processes,並且使用了討論here的SocketHandler方法。我從來沒有任何問題有一個單一的記錄器(沒有套接字),但從我讀的內容來看,我被告知最終會意外失敗。據我所知,它不知道當你試圖同時寫入同一個文件時會發生什麼。我的代碼基本上是執行以下操作:來自多個進程的Python日誌記錄
import logging
log = logging.getLogger(__name__)
def monitor(...):
# Spawn child processes with os.fork()
# os.wait() and act accordingly
def main():
log_server_pid = os.fork()
if log_server_pid == 0:
# Create a LogRecordSocketServer (daemon)
...
sys.exit(0)
# Add SocketHandler to root logger
...
monitor(<configuration stuff>)
if __name__ == "__main__":
main()
所以我的問題是:我需要創建每個os.fork()
後新log
對象?現有的全球對象會發生什麼變化?
以我這樣做的方式,我是否解決了我試圖避免的問題(多個打開的文件/套接字)?這是否會失敗,爲什麼會失敗(我希望能夠判斷未來類似的實現是否會失敗)?
另外,從多個進程登錄到一個文件的「正常」(一個log=
表達式)方法會失敗?它會引發IOError/OSError嗎?或者它只是沒有完全寫入文件的數據?
如果有人可以提供一個答案或鏈接來幫助我,那就太好了。謝謝。
FYI: 我測試在Mac OS X獅子和代碼最終可能會在CentOS 6的VM在Windows機器上運行(如果該事項)。無論我使用什麼解決方案都不需要在Windows上工作,但應該在基於Unix的系統上工作。
更新:這個問題已經開始擺脫日誌記錄的特定行爲,更多地處於linux在fork中對文件描述符做什麼的領域。我拿出了一本大學教科書,似乎如果你從兩個進程(不是分支之前)以附加模式打開一個文件,只要你的寫入沒有超過,他們都能夠正確地寫入文件實際的內核緩衝區(雖然可能需要使用行緩衝,但仍不確定)。這將創建2個文件表條目和一個v節點表條目。打開一個文件然後分叉不應該工作,但似乎只要你沒有像以前那樣超過內核緩衝區(我已經在之前的程序中完成了)。所以我想,如果你想獨立於平臺的多處理日誌記錄你使用套接字,並創建一個新的SocketHandler後,每個叉安全,因爲Vinay下面建議(這應該無處不在)。對我而言,由於我對運行我的軟件的操作系統有很強的控制力,因此我認爲我將使用一個FileHandler(默認情況下以附加模式打開,並在大多數操作系統上進行緩衝行)打開一個全局對象log
。 open
的文檔說:「負緩衝意味着使用系統默認值,通常爲tty設備進行線路緩衝併爲其他文件進行完全緩衝,如果省略,則使用系統默認值。」或者我可以創建自己的日誌流以確保行緩衝。而僅僅是明確的,我確定有:
# Process A
a_file.write("A\n")
a_file.write("A\n")
# Process B
a_file.write("B\n")
生產...
A\n
B\n
A\n
,只要它不產生...
AB\n
\n
A\n
維奈(或其他人),怎麼錯了我是誰?讓我知道。感謝您提供更多清晰/可靠的信息。
線程和鎖對於這樣的事情很有用...... –
我需要單獨的進程,因爲孩子們正在與外部設備進行通信,這些外部設備應該儘可能「快速」。 – daveydave400
我更新了我的答案。 –