主要參考文章:https://www.cnblogs.com/ArsenalfanInECNU/p/10134591.html
threading是python中用於線程相關操作的模塊。python當前版本的多線程庫沒有實現優先級、線程組,線程也不能被停止、暫停、恢復、中斷。本文章主要介紹threading模塊的主要類與函數。
1.threading模塊概覽
threading模塊提供的類:
Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。
threading 模塊提供的常用方法:
threading.currentThread(): 返回當前的線程變量。
threading.enumerate(): 返回一個包含正在運行的線程的list。正在運行指線程啓動後、結束前,不包括啓動前和終止後的線程。
threading.activeCount(): 返回正在運行的線程數量,與len(threading.enumerate())有相同的結果。
threading 模塊提供的常量:
threading.TIMEOUT_MAX 設置threading全局超時時間。
2.threading模塊常用類
2.1 Thread類
Thread是線程類,有兩種使用方法:方法一,直接在target傳入要運行的方法;方法二,或從Thread繼承並覆蓋run()。推薦使用方法一,將目標函數作爲target參數傳入,非常簡單。下面是兩種使用方法:
方法一:
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
def sub_thread(arg):
print("thread arg is :%s\n" % str(arg))
def run_thread():
th_list = []
for i in xrange(5):
t = threading.Thread(target=sub_thread,args=(i,))
th_list.append(t)
t.start()
for t in th_list:
t.join()
if __name__ == '__main__':
run_thread()
輸出:
thread arg is :0
thread arg is :1
thread arg is :2
thread arg is :3
thread arg is :4
方法二:
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
class MyThread(threading.Thread):
def __init__(self, arg):
super(MyThread, self).__init__()
self.arg = arg
def run(self):
print("thread arg is: %s\n" % str(self.arg))
def run_thread():
th_list = []
for i in xrange(5):
t = MyThread(i)
th_list.append(t)
t.start()
for t in th_list:
t.join()
if __name__ == '__main__':
run_thread()
輸出和方法一相同
Thread類的相關方法:
構造方法:
Thread(group=None, target=None, name=None, args=(), kwargs={})
group: 線程組,目前還沒有實現,庫引用中提示必須是None;
target: 要執行的方法;
name: 線程名;
args/kwargs: 要傳入方法的參數。
實例方法:
isAlive(): 返回線程是否在運行。正在運行指啓動後、終止前。
get/setName(name): 獲取/設置線程名。
start(): 線程準備就緒,等待CPU調度
is/setDaemon(bool): 將該子線程設置爲父線程的守護線程(默認爲非守護線程(False))。(需要在線程start之前設置)
start(): 啓動線程。
join([timeout]): 阻塞當前上下文環境的線程,直到調用此方法的線程終止或到達指定的timeout(可選參數)。
下面解釋常用的實例方法:
2.1.1 關鍵參數setDaemon
該參數規定當前線程是否屬於守護線程,需要在線程start之前設置,默認爲非守護線程(False)。
- True: 設置該子進程爲父進程的守護進程,即後臺線程。主線程執行過程中,子線程也在進行,主線程執行完畢後,子線程不論成功與否,主線程和子線程均停止。
- False:設置該子進程爲父進程的非守護進程,即前臺進程。主線程執行過程中,子線程也在進行,主線程代碼執行完畢後,仍需要等待子線程也執行完成後,主線程纔會停止。
當線程設置爲非守護線程時,主線程要等待所有子線程執行完之後,才停止程序。舉例如下:
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
import time
def daemon_test(arg):
time.sleep(1)
print("daemon thread args is: %s\n" % arg)
def run_daemon():
th_list = []
for i in xrange(5):
t = threading.Thread(target=daemon_test, args=(i,))
t.setDaemon(False)
th_list.append(t)
t.start()
if __name__ == '__main__':
run_daemon()
print("main process over")
輸出爲:
main process over
daemon thread args is: 4
daemon thread args is: 1
daemon thread args is: 0
daemon thread args is: 3
daemon thread args is: 2
設置非線程守護時,主線程執行過程中,子線程也在進行,主線程執行完畢後,等待子線程也執行完成後,主線程停止。
當線程設置守護線程時:
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
import time
def daemon_test(arg):
time.sleep(1)
print("daemon thread args is: %s\n" % arg)
def run_daemon():
th_list = []
for i in xrange(5):
t = threading.Thread(target=daemon_test, args=(i,))
t.setDaemon(True)
th_list.append(t)
t.start()
if __name__ == '__main__':
run_daemon()
print("main process over")
輸出:
main process over
設置線程守護時,主線程執行完畢後,無論子線程執行與否,主線程和子線程均停止。
2.1.2 關鍵參數join
作用爲阻塞當前上下文環境的線程,直到調用此方法的線程終止或到達指定的timeout(可選參數)。即當子進程的join()函數被調用時,主線程就被阻塞住了,意思爲不再繼續往下執行。
值得注意的是,由於join()會阻塞其他函數,如果我們要用for循環觸發多個線程的執行,start()要和join()分開,即一次用兩個for循環,先用第一個for循環將全部子線程start(),再用第二個for循環將全部子線程join,不然會讓多線程並行執行,變成多線程依次執行:
- 因爲如果其他線程還沒有start(),那麼由於start()操作屬於主線程的調用,那麼start()會被阻塞,我們原本想要的多線程並行執行會變成多線程依次執行。
- 如果此時其他線程已經start()了,那麼join()函數由於是對子線程的操作,不屬於主線程,則不會被阻塞。
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
import time
def join_test(arg):
time.sleep(1)
print("daemon thread args is: %s\n" % arg)
def run_join():
th_list = []
for i in xrange(5):
t = threading.Thread(target=daemon_test, args=(i,))
t.setDaemon(False)
th_list.append(t)
t.start()
for t in th_list:
t.join()
if __name__ == '__main__':
run_join()
print("main process over")
輸出:
daemon thread args is: 1
daemon thread args is: 0
daemon thread args is: 3
daemon thread args is: 4
daemon thread args is: 2
main process over
2.2 Timer類
Timer(定時器)是Thread的派生類,用於在指定時間後調用一個方法。
構造方法:
Timer(interval, function, args=[], kwargs={})
interval: 指定的時間
function: 要執行的方法
args/kwargs: 方法的參數
實例方法:
Timer從Thread派生,沒有增加實例方法。
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
def timer_test():
print("timer thread start")
if __name__ == '__main__':
t = threading.Timer(3, timer_test)
t.start()
該例子爲3秒之後調用函數