簡體   English   中英

Python Multiprocessing 在 Windows 上使用 Logging 和運行凍結返回結果

[英]Python Multiprocessing returning results with Logging and running frozen on Windows

我需要一些幫助來在多處理和運行 Windows 下凍結的應用程序時實現日志記錄。 關於這個主題有幾十個主題,我花了很多時間來回顧和測試它們。 我還廣泛審查了文檔,但我無法弄清楚如何在我的代碼中實現這一點。

我創建了一個最小示例,它在 Linux 上運行良好,但在 Windows 上崩潰(即使沒有凍結)。 我創建的示例只是我對代碼進行的許多迭代之一。

您可以在 github 上找到最小示例 任何使此示例工作的幫助將不勝感激。

謝謝你。

馬克。

基礎的

在 Linux 上,默認情況下通過fork方法創建子進程。 這意味着,子進程幾乎繼承了父進程的所有內容。

在 Windows 上,子進程是通過spawn方法創建的。 這意味着,子進程幾乎從崩潰開始, if __name__ == '__main__' ,則重新導入並重新執行保護雲之外的任何代碼。

為什么它有效或失敗

在 Linux 上,由於logger對象是繼承的,您的程序將開始記錄。 但它遠非完美,因為您直接登錄到文件。 由於進程之間的競爭條件,遲早會發生日志行重疊或文件上的IO錯誤。

在 Windows 上,由於您沒有將logger對象傳遞給子進程,並且它重新導入了您的pymp_global模塊,因此logger是一個None對象。 因此,當您嘗試使用None對象進行日志記錄時,它肯定會崩潰。

解決方案

使用多處理進行日志記錄並不是一件容易的事。 要使其在 Windows 上工作,您必須將記錄器對象傳遞給子進程和/或使用QueueHandler記錄。 另一個類似的進程間通信解決方案是使用SocketHandler

這個想法是只有一個線程或進程進行日志記錄。 其他進程只發送日志記錄。 這可以防止競爭條件並確保在關鍵進程有時間完成其工作后寫出日志。

那么如何實施呢?
我之前遇到過這個日志問題並且已經編寫了代碼。
您可以將它與logger-tt包一起使用。

#pymp.py
from logging import getLogger
from logger_tt import setup_logging    

setup_logging(use_multiprocessing=True)
logger = getLogger(__name__)
# other code below

對於其他模塊

#pymp_common.py
from logging import getLogger

logger = getLogger(__name__)
# other code below

這使您無需在任何地方手動編寫所有日志記錄配置代碼。 您可以考慮更改log_config文件以滿足您的需要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM