當進程終止時,所有線程都會終止。因此,如果您的主程序在try..except
之後結束,則所有三個線程可能會提前終止。例如:
import thread
import logging
import time
logger = logging.getLogger(__name__)
def start(taskname, n):
for i in range(n):
logger.info('{}'.format(i))
time.sleep(0.1)
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s %(threadName)s] %(message)s',
datefmt='%H:%M:%S')
try:
thread.start_new_thread(start, ("task1", 10))
thread.start_new_thread(start, ("task2", 5))
thread.start_new_thread(start, ("task3", 8))
except Exception as err:
logger.exception(err)
可以打印出類似這樣
[14:15:16 Dummy-3] 0
[14:15:16 Dummy-1] 0
相反,如果你把
time.sleep(5)
在腳本的末尾,那麼你看到所有的充分預期輸出三個 線程。
還要注意,線程模塊是低級模塊;除非你有使用它的特殊原因,否則大多數人通常使用線程模塊,它可以實現更多有用的線程處理功能,例如在線程完成之前會阻塞的方法,如join
。見下面的例子。
The docs state:
當函數返回時,線程自行退出。 當函數以未處理的異常終止時,將打印一個堆棧跟蹤 ,然後該線程退出(,但其他線程繼續運行)。
因此,默認情況下,當一個線程完成時,其他線程繼續運行。 上面的例子也證明了這一點。
使一個函數完成時所有線程退出更困難。 一個線程不能殺死另一個線程乾淨(例如,而不殺死整個 過程。)使用threading
,你可以安排線程設置一個變量 (如flag
)爲True時結束,並有各線程定期檢查 flag
的狀態,如果它爲True,則退出。但請注意,其他線程 不一定終止立即;他們只會在他們下一次 檢查flag
的狀態時終止。如果線程被阻塞,例如等待I/O,則 然後它可能不檢查flag
相當長的時間(如果有的話!)。
但是,如果線程大部分時間處於一個快速循環,你可以檢查每次迭代一次flag
狀態:
import threading
import logging
import time
logger = logging.getLogger(__name__)
def start(taskname, n):
global flag
for i in range(n):
if flag:
break
logger.info('{}'.format(i))
time.sleep(0.1)
else:
# get here if loop finishes without breaking
logger.info('FINISHED')
flag = True
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s %(threadName)s] %(message)s',
datefmt='%H:%M:%S')
threads = list()
flag = False
try:
threads.append(threading.Thread(target=start, args=("task1", 10)))
threads.append(threading.Thread(target=start, args=("task2", 5)))
threads.append(threading.Thread(target=start, args=("task3", 8)))
except Exception as err:
logger.exception(err)
for t in threads:
t.start()
for t in threads:
# make the main process wait until all threads have finished.
t.join()
非常豐富和適用於即時通訊工作,謝謝。爲了您對號碼2的回答,是否需要調用thread.start()?開始和加入有什麼區別? – Kiddo
開始將啓動線程。加入將等待線程完成 - 它不會啓動它 –
因此對於循環中的2 /我們必須同時加入()和開始()才能工作,這是正確的嗎? – Kiddo