源代碼中 Threading.join() 的順序是否保證了執行緒的執行順序,或者只是確保主執行緒完成直到所有執行緒完成?
import threading, time
class myThread(threading.Thread):
def __init__(self, threadID, name, duerme):
super(myThread, self).__init__()
self.threadID = threadID
self.name = name
self.duerme = duerme
def run(self):
print("run()", self.name)
time.sleep(self.duerme)
print("%s termino " % self.name)
thread1 = myThread(1, "Thread-1", 20)
thread2 = myThread(2, "Thread-2", 12)
thread3 = myThread(3, "Thread-3", 6)
thread2.start()
thread1.start()
thread3.start()
thread3.join()
thread1.join()
thread2.join()
print("termino el hilo principal")
輸出:
run() Thread-2
run() Thread-1
run() Thread-3
Thread-3 termino
Thread-2 termino
Thread-1 termino
termino el hilo principal
如果是這樣,我可以將其視為一個“鉤子”(告訴我 join()s 下面的代碼肯定會在執行緒結束后執行),它只是告訴我執行緒何時結束?
如果我在 join()s 之間放置代碼(我更改了最后一部分):
thread3.join()
print("debajo del thread3")
thread1.join()
print("debajo del thread1")
thread2.join()
print("debajo del thread2")
print("termino el hilo principal")
我明白了:
run() Thread-2
run() Thread-1
run() Thread-3
Thread-3 termino
debajo del thread3
Thread-2 termino
Thread-1 termino
debajo del thread1
debajo del thread2
termino el hilo principal
就好像短語“debajo del thread2”正在等待 thread1。
預期輸出:
run() Thread-2
run() Thread-1
run() Thread-3
Thread-3 termino
debajo del thread3
Thread-2 termino
debajo del thread2
Thread-1 termino
debajo del thread1
termino el hilo principal
uj5u.com熱心網友回復:
原始碼中Threading.join()s的順序是否保證了執行緒的執行順序
你問的是哪些執行緒?如果您詢問、 和的執行順序thread1,那么答案是,絕對不是。當您呼叫它時,它根本不會對 thread 做任何事情。IMO,最好的想法是,它什么都不做,它一直什么都不做,直到執行緒完成,然后它回傳。thread2thread3t.join()tjoint
OTOH,如果您詢問您的主執行緒,那么是的,當您的主執行緒呼叫時threadN.join(),您的主執行緒將被“阻塞”直到threadN完成。
...執行緒的執行順序...
您thread1的thread2、 和thread3完全不同步。它們同時運行。*“并發”意味著不能保證哪個執行緒做什么,什么時候做,除非他們做了一些明確同步它們的事情。
顯式同步的一個示例是,如果一個執行緒釋放了某個其他執行緒正在等待的互斥鎖。保證等待互斥鎖的執行緒在第一個執行緒釋放它之前不會繼續。
同步執行緒的另一個例子是join. 當執行緒 A 加入執行緒 B 時,執行緒 A 保證在執行緒 B 結束之前不會繼續。
* 并發處理是使用執行緒的全部意義。如果您不想要并發,請不要使用執行緒。
uj5u.com熱心網友回復:
所以回答你的問題:
原始碼中Threading.join()s的順序是否保證了執行緒的執行順序
答案是否定的。執行順序可以通過使用鎖(互斥鎖,信號量,...)來處理。它們允許您同步某些代碼片段,以便一次只有一個執行緒可以獨占訪問原子運算式或共享資料。但是順序總是隨機的,這沒關系,因為執行緒應該是這樣作業的。
在并行環境中,您并不真正知道執行緒 A是先執行還是在執行緒 B之后執行或完成。
如果要確保它們同步(A 先執行,B 在 A 之后執行),請不要使用執行緒。一個接一個地在主執行緒上使用他們的指令。
還是只是確保主執行緒完成直到所有執行緒完成?
不一定。如果您不想等待執行緒完成,那沒關系。Python 或作業系統應該以適當的方式處理它的破壞(除非發生錯誤,這可能會發生)。
Thread.join()如果您需要等待(阻止當前執行緒)該單個執行緒完成,則應呼叫它。
在我看來,在每個腳本的末尾加入一個執行緒是一種很好的做法,這樣您就知道一旦應用程式完成執行就會釋放資源。但是,在互聯網上找到的許多答案中,甚至在 SO 上,它都表示這取決于你想要做什么。如果執行緒需要在應用程式執行完成后運行,它的資源將在執行緒完成操作后釋放。
如果是這樣,我可以將其視為一個“鉤子”(告訴我 join()s 下面的代碼肯定會在 AFTER THREADS END 之后執行),它只是告訴我執行緒何時結束?
再次。它不會告訴執行緒是否已經結束。它阻塞當前執行緒,直到目標執行緒完成執行(Thread.run()超出范圍)。
這是一個按此處None所述回傳的阻塞函式。如果您需要知道執行緒是否仍在運行,請使用.Thread.is_alive()
現在關于您的編輯:
如果我在 join()s 之間放置代碼(我更改了最后一部分):
thread3.join() print("debajo del thread3") thread1.join() print("debajo del thread1") thread2.join() print("debajo del thread2") print("termino el hilo principal")我明白了:
run() Thread-2 run() Thread-1 run() Thread-3 Thread-3 termino debajo del thread3 Thread-2 termino Thread-1 termino debajo del thread1 debajo del thread2 termino el hilo principal
這是您的執行緒的作業方式:
- 當他們開始時,他們列印
run字串。 - 他們等待預定的秒數。
- 執行緒 1等待20 秒
- 執行緒 2等待12 秒
- 執行緒 3等待6 秒
- 當他們完成等待時,他們列印
termino字串。
所以,讓我們運行腳本!所有執行緒現在開始。每個執行緒的啟動順序大多是隨機的。執行緒 2可以首先開始,或者執行緒 1可能是最后一個。順序取決于 OS / Python 解釋器如何調度執行緒執行。
無論哪個先啟動,一旦到達time.sleep()函式,它們都會卡住,等待自己的超時。
在此等待期間,主執行緒同時加入Thread 3。它阻塞自己(而其他執行緒仍在休眠),并等待執行緒 3喚醒并超出范圍。
6 秒或更長時間后,就會發生這種情況。執行緒 3 超出范圍,列印Thread-3 termino字串。
現在,主執行緒再次回應,并在執行緒 1和執行緒 2仍在休眠時執行下一條指令。它加入Thread 1,凍結自身,直到Thread 1超出范圍。
12 秒過去了,執行緒 2超出范圍,列印Thread-2 termino字串。20 秒過去了,執行緒 1超出范圍,也列印出來了Thread-1 termino。然后,主執行緒再次回應,并執行下一條指令:join Thread 2。
它會凍結自己,等待執行緒 2超出范圍。但是這個執行緒已經完成了。所以等待是即時的,主執行緒移動到下一條指令,直到腳本完成執行。
這就是根據您撰寫的腳本應該發生的事情。Thread.join()不控制哪個執行緒首先完成執行。Thread.run()它控制在執行緒超出其方法的范圍后主執行緒是否可以繼續。雖然Thread.join()已被呼叫,并且當前執行緒進入睡眠狀態,但所有其他執行緒將繼續正常執行,因為它們是并行運行的。它們甚至可能在加入的執行緒喚醒當前執行緒之前超出范圍。
uj5u.com熱心網友回復:
謝謝伙計們,現在我理解了 join(),因為我把 80 的時間放在執行緒 1 和 100 的時間到執行緒 2,我可以注意到你告訴我的內容。訊息 "print("below thread1")" 和 "print("below thread2")" 一起出現(一個接一個),因為當 thread1 結束時,thread2 已經結束了“這就是為什么“等待”的影響不清楚”。
絕對可以將 Threading.join() 視為當前執行緒的一種“Thread.sleep()”,直到 t.join() 完成。
對不起大家,我是執行緒新手,但這是這個世界上最難理解的事情。現在困難的部分是選擇最佳答案呵呵。
所以我留下代碼以防你想了解 join() 的“等待”:
import threading, time
class myThread(threading.Thread):
def __init__(self, threadID, name, duerme):
super(myThread, self).__init__()
self.threadID = threadID
self.name = name
self.duerme = duerme
def run(self):
print("run()", self.name)
time.sleep(self.duerme)
print("%s termino " % self.name)
thread1 = myThread(1, "Thread-1", 80)
#I had to increase the wait of thread 2 so that the wait of the current
#thread is appreciated (and the "interleaved" messages that SHOW THE
#WAIT are visible).
thread2 = myThread(2, "Thread-2", 100)
thread3 = myThread(3, "Thread-3", 6)
thread2.start()
thread1.start()
thread3.start()
thread3.join()
print("debajo del thread3")
print("antes de thread1.join()")
thread1.join()
print("debajo del thread1")
thread2.join()
print("debajo del thread2")
print("termino el hilo principal")
輸出:
run() Thread-2
run() Thread-1
run() Thread-3
Thread-3 termino
debajo del thread3
antes de thread1.join()
Thread-1 termino
debajo del thread1 //This was the hard to see effect
Thread-2 termino
debajo del thread2
termino el hilo principal
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/517044.html
上一篇:Java中的并發安全佇列
下一篇:單獨執行緒中的快速IO操作
