該包在 Python 2 中屬於正常可用狀態,但在 Python 3 中處於即將廢棄的狀態,雖然還可以用,但包名被改為 _thread。
使用 thread 包首先要引入該包,在 Python 2 中使用下面的語句來引入:
import thread
而在 Python 3 中,由於包名從 thread 改為了 _thread,所以需要使用下面的語句來引入:
import _thread
為了保持一致性,可以首先判斷當前使用的是 Python 2 還是 Python 3,然後引入不同的包,並在 Python 3 中將包重新命名為 thread。程式碼如下:
import sysif sys。version_info。major == 2: # Python 2 import threadelse: # Python 3 import _thread as thread
執行緒的啟動
在 thread 包中,需要定義一個函式作為執行緒的入口。我們可以編寫下面的一個函式,其每隔一秒鐘就列印一句話,列印 10 次後退出。程式碼如下:
def thread_entry(id): cnt = 0 while cnt < 10: # 迴圈次數不夠print(‘Thread:(%d) Time:%s’ % (id, time。ctime()))time。sleep(1) # 休息一秒cnt = cnt + 1
另外,如果需要啟動某個執行緒,可以使用下面的方法:
start_new_thread(function, args[, kwargs])
該方法的第一個引數 function 表示要執行的函式,如上面定義的函式名,該函式將作為執行緒的入口函式使用。args 和kwargs是該函式的引數,args是必須的,型別是元組;kwargs是可選的,型別是字典。
這裡僅使用 args,而且只有一個引數,程式碼如下:
def start_threads(): t1 = thread。start_new_thread(thread_entry, (1,)) # 啟動執行緒1 t2 = thread。start_new_thread(thread_entry, (2,)) # 啟動執行緒2 time。sleep(12) # 等待
函式 start_threads() 將會啟動兩個執行緒,每個執行緒都是以 thread_entry() 作為入口函式。下面是完整的程式碼。
import time, sys # 引入time和sys模組if sys。version_info。major == 2: # 如果當前使用的是Python 2直譯器 import threadelse: # 當前使用的是Python 3直譯器 import _thread as threaddef thread_entry(id): # 定義入口函式cnt = 0while cnt < 10: #迴圈10次,每次列印一行 print(‘Thread:(%d) Time:%s’ % (id, time。ctime())) time。sleep(1) cnt = cnt + 1def start_threads(): # 啟動執行緒 t1 = thread。start_new_thread(thread_entry, (1,)) t2 = thread。start_new_thread(thread_entry, (2,)) time。sleep(12)if __name__==‘__main__’: # 執行指令碼 start_threads()
執行該指令碼,輸出如下:
$ python3 createThreadDemo1。py
Thread:(1) Time:Fri May 10 06:00:29 2019 # 執行緒1第9行輸出
Thread:(2) Time:Fri May 10 06:00:29 2019 # 執行緒2第9行輸出
Thread:(2) Time:Fri May 10 06:00:30 2019 # 執行緒2第9行輸出
Thread:(1) Time:Fri May 10 06:00:30 2019 # 執行緒1第9行輸出
Thread:(2) Time:Fri May 10 06:00:31 2019
Thread:(1) Time:Fri May 10 06:00:31 2019 # 執行緒1第9行輸出
Thread:(2) Time:Fri May 10 06:00:32 2019 # 執行緒2第9行輸出
Thread:(1) Time:Fri May 10 06:00:32 2019
Thread:(2) Time:Fri May 10 06:00:33 2019 # 執行緒2第9行輸出
Thread:(1) Time:Fri May 10 06:00:33 2019 # 執行緒1第9行輸出
Thread:(2) Time:Fri May 10 06:00:34 2019
Thread:(1) Time:Fri May 10 06:00:34 2019 # 執行緒1第9行輸出
Thread:(2) Time:Fri May 10 06:00:35 2019 # 執行緒2第9行輸出
Thread:(1) Time:Fri May 10 06:00:35 2019 # 執行緒1第9行輸出
Thread:(2) Time:Fri May 10 06:00:36 2019
Thread:(1) Time:Fri May 10 06:00:36 2019 # 執行緒1第9行輸出
Thread:(2) Time:Fri May 10 06:00:37 2019 # 執行緒2第9行輸出
Thread:(1) Time:Fri May 10 06:00:37 2019 # 執行緒1第9行輸出
Thread:(2) Time:Fri May 10 06:00:38 2019
Thread:(1) Time:Fri May 10 06:00:38 2019
可以看到 Tread1 和 Tread2 交錯執行,並不是某一個執行緒執行完之後另外一個再執行。這兩個執行緒的執行順序並沒有特定的規律,具有一定的隨機性,所以兩個執行緒可以看作是並行的。
執行緒的退出
上面介紹瞭如何定義入口函式和啟動執行緒,那麼執行緒如何退出呢?有下面幾種退出方式:
入口函式執行完畢。
執行緒丟擲沒有處理的異常。
執行緒內部呼叫_thread。exit_thread()來退出。
前面的例子是透過入口函式執行完畢來退出執行緒的,下面的例子演示了使用 _thread。exit_thread() 來退出執行緒的方法。在這個例子中,入口函式透過一個全域性變數來判斷是否需要退出。而這個全域性變數是被主執行緒來控制的。完整程式碼如下:
import time, sysif sys。version_info。major == 2: # Python 2 import threadelse: # Python 3 import _thread as threadg_continue = True # 繼續執行的標誌def thread_entry(id): # 執行緒入口函式 global g_continue while True: if not g_continue: # 如果標誌為False,退出 print(“Thread:(%d) exit” % id) thread。exit_thread() # 退出執行緒 else: print(‘Thread:(%d) Time:%s’ % (id, time。ctime())) time。sleep(1)def start_threads(): # 啟動執行緒 global g_continue t1 = thread。start_new_thread(thread_entry, (1,)) # 啟動執行緒1 t2 = thread。start_new_thread(thread_entry, (2,)) # 啟動執行緒2 time。sleep(3) g_continue = False # 修改標誌 time。sleep(2)if __name__==‘__main__’: start_threads()
執行結果如下:
$ python3 createThreadDemo2。py # 執行
Thread:(1) Time:Fri May 10 06:16:35 2019 # 執行緒1在執行
Thread:(2) Time:Fri May 10 06:16:35 2019 # 執行緒2在執行
Thread:(1) Time:Fri May 10 06:16:36 2019
Thread:(2) Time:Fri May 10 06:16:36 2019
Thread:(2) Time:Fri May 10 06:16:37 2019
Thread:(1) Time:Fri May 10 06:16:37 2019
Thread:(1) exit # 執行緒1退出
Thread:(2) exit # 執行緒2退出