Python中使用線程有三種方式:
方法一:函數式
調用thread模塊中的start_new_thread()函數來產生新線程。語法如下:
thread.start_new_thread ( function, args[, kwargs] )
參數說明:
- function - 線程函數。
- args - 傳遞給線程函數的參數,他必須是個tuple類型。
- kwargs - 可選參數。
實例:
線程的結束一般依靠線程函數的自然結束;也可以在線程函數中調用thread.exit(),他拋出SystemExit exception,達到退出線程的目的。
方法二:通過繼承threading.Thread創建線程
使用Threading模塊創建線程,直接從threading.Thread繼承,然後重寫__init__方法和run方法:
實例
方法三:使用threading.Thread直接在線程中運行函數。
線程模塊
Python通過兩個標準庫thread和threading提供對線程的支持。thread提供了低級別的、原始的線程以及一個簡單的鎖。
thread 模塊提供的其他方法:
- threading.currentThread(): 返回當前的線程變量。
- threading.enumerate(): 返回一個包含正在運行的線程的list。正在運行指線程啓動後、結束前,不包括啓動前和終止後的線程。
- threading.activeCount(): 返回正在運行的線程數量,與len(threading.enumerate())有相同的結果。
除了使用方法外,線程模塊同樣提供了Thread類來處理線程,Thread類提供了以下方法:
- run(): 用以表示線程活動的方法。
-
start():啓動線程活動。
- join([time]): 等待至線程中止。這阻塞調用線程直至線程的join() 方法被調用中止-正常退出或者拋出未處理的異常-或者是可選的超時發生。
- isAlive(): 返回線程是否活動的。
- getName(): 返回線程名。
- setName(): 設置線程名。
-
setDaemon方法。
在腳本運行的過程中有一個主線程,如果主線程又創建了一個子線程,那麼當主線程退出時,會檢驗子線程是否完成。如果子線程未完成,則主線程會在等待子線程完成後退出。
當需要主線程退出時,不管子線程是否完成都隨主線程退出,則可以使用Thread對象的setDaemon方法來設置。
線程同步
1.簡單的線程同步
使用Thread對象的Lock和RLock可以實現簡單的線程同步。對於如果需要每次只有一個線程操作的數據,可以將操作過程放在acquire方法和release方法之間。如:
實例:
結果將是輸出10個30。30是x的最終值,由於x是全局變量,每個線程對其操作後進入休眠狀態,在線程休眠的時候,python解釋器就執行了其他的線程而是x的值增加。當所有線程休眠結束後,x的值已被所有線修改爲了30,因此輸出全部爲30。
下面再看看加鎖的實例
2、使用條件變量保持線程同步。
Python的Condition對象提供了對複製線程同步的支持。使用Condition對象可以在某些事件觸發後才處理數據。Condition對象除了具有acquire方法和release的方法外,還有wait方法、notify方法、notifyAll方法等用於條件處理。
實例:
線程間通信:
Event對象用於線程間的相互通信。他提供了設置信號、清除信宏、等待等用於實現線程間的通信。
1、設置信號。Event對象使用了set()方法後,isSet()方法返回真。
2、清除信號。使用Event對象的clear()方法後,isSet()方法返回爲假。
3、等待。當Event對象的內部信號標誌爲假時,則wait()方法一直等到其爲真時才返回。還可以向wait傳遞參數,設定最長的等待時間。
實例:
線程優先級隊列( Queue)
Python的Queue模塊中提供了同步的、線程安全的隊列類,包括FIFO(先入先出)隊列Queue,LIFO(後入先出)隊列LifoQueue,和優先級隊列PriorityQueue。這些隊列都實現了鎖原語,能夠在多線程中直接使用。可以使用隊列來實現線程間的同步。
Queue模塊中的常用方法:
- Queue.qsize() 返回隊列的大小
- Queue.empty() 如果隊列爲空,返回True,反之False
- Queue.full() 如果隊列滿了,返回True,反之False
- Queue.full 與 maxsize 大小對應
- Queue.get([block[, timeout]])獲取隊列,timeout等待時間
- Queue.get_nowait() 相當Queue.get(False)
- Queue.put(item) 寫入隊列,timeout等待時間
- Queue.put_nowait(item) 相當Queue.put(item, False)
- Queue.task_done() 在完成一項工作之後,Queue.task_done()函數向任務已經完成的隊列發送一個信號
- Queue.join() 實際上意味着等到隊列爲空,再執行別的操作
實例: