使用執行緒時,您正在尋找同時快速執行多個實體, .join() 不會通過在啟動之前等待每個執行緒完成來破壞該目的,這在本質上與常規回圈。當不使用 join 時,執行緒會在啟動時盡快觸發。我的問題可能聽起來很幼稚,因為我仍在努力學習。
假設 itemsArr 有 1000 個專案,itemQueryRequest 執行需要 3 秒,您希望每個專案都盡可能地在同一時間被查詢,因此您使用執行緒。
此外,一旦目標函式完成,無論連接如何,執行緒都會死亡,所以你......我錯過了什么。
#lightning fast
import threading
for item in itemsArr:
t = Thread(target=itemQueryRequest, args=(item,))
t.start()
# SLOW
th = []
for item in itemsArr:
t = Thread(target=itemQueryRequest, args=(item,))
th.append(t)
th.start()
th.join() // < SLOW
uj5u.com熱心網友回復:
你是對的,如果你join()在啟動一個執行緒后立即呼叫,它違背了擁有一個執行緒的目的,因為現在你有一個子執行緒正在運行但是你的主執行緒被阻塞直到子執行緒回傳,因此你仍然沒有任何并行性。
但是,join()不打算以這種方式使用。相反,預計您將有start()一個或多個執行緒,然后主執行緒將繼續執行(無論它通常做什么),或者它將呼叫join() 每個啟動的執行緒以阻塞直到所有執行緒已經退出。在這兩種情況中的任何一種情況下,您仍然實作了有效的并行性(盡管有 Python GIL)。
join()然而,的真正目的是讓您安全地釋放資源。一方面,有一些與每個執行緒相關的底層資源(例如它的回傳值)需要保留在記憶體中,直到join()(或detach()) 被呼叫,以防父執行緒想要使用它們;更重要的是,如果父執行緒已經分配了子執行緒可以訪問的一些資源,那么在子執行緒退出之前父執行緒釋放該資源通常是不安全的,因為在子執行緒處于中間使用它會給子執行緒帶來很大的問題。
類似地,如果子執行緒正在準備一些資料供父執行緒使用,那么在子執行緒完成準備之前,父執行緒嘗試使用該資料是不安全的——嘗試使用是沒有意義的半構建的資料。
鑒于此,join()在執行任何會影響子執行緒的清理作業之前,父執行緒呼叫等待子執行緒退出是很常見的。
如果子執行緒沒有設計為在有限的時間內自動退出,主執行緒可能會在join()呼叫之前請求子執行緒退出,例如通過設定布爾變數或在管道上寫入一個位元組,或等等,并且子執行緒會通過退出來對此做出反應,這樣join()呼叫就不會無限期地阻塞。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/382677.html
上一篇:將`Var`從`Arc<Mutex<Var>>`移出
下一篇:行程和執行緒之間共享和更新串列
