Python thread模組用法詳解

該包在 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退出