在編寫多線程程序時,有時候需要主線程等待子線程完成後再進行下一步操作。這個功能很常見,我們可以通過各種方式來實現。下面從多個方面來討論主線程等待子線程結束繼續執行的實現方式。
一、使用join()函數等待子線程結束
join()函數是一個線程對象的方法,用於等待線程執行完成。主線程調用join()函數會被阻塞,直到子線程執行完畢才會繼續執行。
import threading import time def worker(): print("子線程開始執行") time.sleep(2) print("子線程執行完畢") thread = threading.Thread(target=worker) thread.start() print("主線程開始執行") thread.join() print("主線程執行完畢")
上面的代碼中,主線程調用了子線程的join()方法,主線程會被阻塞,直到子線程執行完畢才會繼續執行。如果沒有調用join()方法,則主線程會在子線程啟動後立即執行完畢。
二、使用Semaphore等待子線程結束
Semaphore信號量是一種線程同步的原語。可以用它來實現線程之間的資源競爭和協作。Semaphore有一個計數器,當計數器大於0時,可以繼續執行。當計數器為0時,需要等待其他線程釋放Semaphore才能繼續執行。
下面的示例使用Semaphore來實現主線程等待子線程完成的功能:
import threading import time sem = threading.Semaphore(0) def worker(): print("子線程開始執行") time.sleep(2) print("子線程執行完畢") sem.release() thread = threading.Thread(target=worker) thread.start() print("主線程開始執行") sem.acquire() print("主線程執行完畢")
在上面的代碼中,Semaphore的計數器初始值為0,當子線程運行完畢後,調用Semaphore的release()方法釋放資源,使得Semaphore的計數器增加1。主線程在調用acquire()方法時會被阻塞,直到子線程執行完畢後釋放資源,使得Semaphore的計數器增加1,主線程才會繼續執行。
三、使用Event等待子線程結束
Event是一種線程同步的原語,可以用它來實現線程之間的協作。一個線程等待另一個線程設置Event信號才能繼續執行。
下面是一個使用Event等待子線程結束的示例:
import threading import time event = threading.Event() def worker(): print("子線程開始執行") time.sleep(2) print("子線程執行完畢") event.set() thread = threading.Thread(target=worker) thread.start() print("主線程開始執行") event.wait() print("主線程執行完畢")
在上面的代碼中,主線程執行到event.wait()時會被阻塞,直到子線程執行完畢後設置Event信號使得event.is_set()返回True,主線程才會繼續執行。
四、使用Queue等待子線程結束
Queue是一個線程安全的隊列,可以用它來實現線程之間的協作和通信。主線程向隊列中放置任務,子線程從隊列中取出任務並執行。當隊列為空時,子線程會阻塞等待。
下面是一個使用Queue等待子線程結束的示例:
import threading import time import queue q = queue.Queue() def worker(): while True: task = q.get() if task is None: break print(f"子線程開始執行任務{task}") time.sleep(2) print(f"子線程執行完畢任務{task}") print("子線程執行完畢") thread = threading.Thread(target=worker) thread.start() print("主線程開始執行") for i in range(3): q.put(i) thread.join() q.put(None) print("主線程執行完畢")
在上面的代碼中,主線程向隊列中放置3個任務,子線程不斷從隊列中取出任務並執行,直到取出任務為None時退出循環。主線程在子線程執行完畢後向隊列中再放置一個空任務,使得子線程能夠退出循環。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/237263.html