TLDR:無法在 中傳遞堆疊跟蹤multiprocessing.Queue,并且當我在該佇列中傳遞錯誤時,一旦在消耗佇列的其他作業人員(執行緒或行程)中接收到它們的堆疊跟蹤,它們就會被剝離。我如何傳遞堆疊跟蹤以便在其消費者的佇列的另一側恢復它?
長問題:
好的,假設我有兩個 Python 工人。這兩個工人屬于同一型別。這意味著它們可以是執行緒或行程:
from multiprocessing import Processfrom threading import Thread
好的,現在假設它是一個執行緒,以使事情變得更簡單,但我希望事情可以與行程互換并且同樣作業。
所以我試圖有很好的堆疊跟蹤來正確報告錯誤。我使用 amultiprocessing.Queue在作業人員之間傳遞資料,最后一個主執行緒輪詢佇列以獲取所有內容,以便在最后加入并關閉所有內容。
如果主執行緒從佇列中收到例外,那么我希望它重新引發它。
但是,一旦在主執行緒中使用,例外就沒有剩余的堆疊跟蹤。當我通過堆疊跟蹤時,佇列似乎中斷了。我想重新提升主執行緒中的所有內容,以使事情可以除錯和記錄盡可能多的細節,因為我需要處理這個并且有一些細節級別。
我能做些什么?
uj5u.com熱心網友回復:
您不能將堆疊跟蹤傳遞到佇列中,因為它們不可提取,請參閱此問題。
但是,如果您只想使用其原始回溯重新引發例外,那么圍繞它的黑客使用了這樣一個事實,即BaseExceptions它的子類是可腌制的。然后,您要做的是傳遞引發的例外型別以及字串化的回溯訊息。然后,您可以使用另一端的回溯隨意提升它:
import traceback
from multiprocessing import Queue, Process
def producer(q):
try:
raise RuntimeError('oh noo')
except Exception as e:
msg = "{}\n\nOriginal {}".format(e, traceback.format_exc())
q.put((e, msg))
if __name__ == "__main__":
q = Queue()
w = Process(target=producer, args=(q, ))
w.start()
w.join()
exc = q.get()
raise type(exc[0])(exc[1])
注意:訊息中有附加內容是有原因Original Traceback的。這是因為子行程中引發的例外回溯可能會丟失,并且在處理管理器和代理時只會導致 multiprocessing.RemoteError。從multiprocessing.BaseProxy的檔案中:
如果呼叫引發例外,則_callmethod() 會重新引發例外。如果在管理器的行程中引發了一些其他例外,那么這將轉換為 RemoteError 例外并由 _callmethod() 引發。
因此,發送原始回溯對于除錯至關重要。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/496641.html
標籤:Python 多线程 多处理 python-多线程 追溯
上一篇:Python:如果佇列突然從另一個執行緒/行程中銷毀,執行緒是否會在掛起`Queue.get(block=True)`呼叫時解除阻塞?
