線程的核心特徵就是他們可以以非肯定的方式(即什麼時候開始執行,什麼時候被打斷,什麼時候恢復徹底由操做系統來調度管理,這是用戶和程序員沒法肯定的)獨立執行的,若是程序中有其餘線程須要判斷某個線程是否已經到達執行過程當中的某個點,根據這個判斷來執行後續的操做,那麼這就產生了很是棘手的線程同步問題,要解決這個問題,咱們可使用threading庫中的Event對象。
Event對象和條件標記相似,容許線程等待某個事件發生。初始狀態時事件被設置爲0,若是事件沒有被設置而線程正在等待該事件,,那麼線程就會被阻塞,直到事件被設置爲止.當有線程設置了這個事件時,就會喚醒全部正在等待該事件的線程,若是線程等待的事件已經設置了,那麼線程會繼續執行python
下面給出了一個簡單的示例,使用Event來同步線程的啓動程序員
#!/usr/bin/env python from threading import Thread,Event import time def countdown(n,started_evt): print 'countdown starting' started_evt.set() while n>0: print n n-=1 time.sleep(5) started_evt=Event() print 'Launching countdown' t=Thread(target=countdown,args=(3,started_evt)) t.start() started_evt.wait() print 'countdown is running'
當運行這段代碼的時候,字符串'countdown is running'老是會在‘countdown starting’以後顯示,這裏使用了事件來同步線程,使得主線程等待,直到countdown()函數首先打印啓動信息以後採開始執行多線程
vent對象實現了簡單的線程通訊機制,它提供了設置信號,清楚信號,等待等用於實現線程間的通訊。函數
1 設置信號操作系統
使用Event的set()方法能夠設置Event對象內部的信號標誌爲真。Event對象提供了isSet()方法來判斷其內部信號標誌的狀態。當使用event對象的set()方法後,isSet()方法返回真線程
2 清除信號code
使用Event對象的clear()方法能夠清除Event對象內部的信號標誌,即將其設爲假,當使用Event的clear方法後,isSet()方法返回假對象
3 等待事件
Event對象wait的方法只有在內部信號爲真的時候纔會很快的執行並完成返回。當Event對象的內部信號標誌位假時,則wait方法一直等待到其爲真時才返回。字符串
#!/usr/bin/env python import threading import time class MyThread(threading.Thread): def __init__(self,signal): threading.Thread.__init__(self) self.signal=signal def run(self): print "I am %s,i will sleep.."%self.name self.signal.wait() print "I am %s,i awake.."%self.name if __name__=='__main__': signal=threading.Event() for t in range(0,3): thread=MyThread(signal) thread.start() print "main thread sleep 3 seconds..." time.sleep(1) signal.set()
root@hanfeifei-HP-ProDesk-680-G2-MT:/mnt/han# python event1.py I am Thread-1,i will sleep.. I am Thread-2,i will sleep.. I am Thread-3,i will sleep.. main thread sleep 3 seconds... I am Thread-3,i awake.. I am Thread-2,i awake.. I am Thread-1,i awake..
Event內部包含了一個標誌位,初始的時候爲false。
可使用使用set()來將其設置爲true;
或者使用clear()將其重新設置爲false;
可使用is_set()來檢查標誌位的狀態;
另外一個最重要的函數就是wait(timeout=None),用來阻塞當前線程,直到event的內部標誌位被設置爲true或者timeout超時。若是內部標誌位爲true則wait()函數理解返回。
~