Python多線程編程(三):threading模塊的類與函數之基本類

主要參考文章: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秒之後調用函數

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章