多線程之間的通信在任何語言一直是個難點。Python提供了非常簡單的通信機制 Threading.Event,通用的條件變量。多個線程可以等待某個事件的發生,在事件發生后,所有的線程都會被激活。
Threading.Event 官方解釋:
"
This is one of the simplest mechanisms for communication between threads: one thread signals an event and other threads wait for it.
An event object manages an internal flag that can be set to true with the set() method and reset to false with the clear() method. The wait() method blocks until the flag is true.
"
我自己的理解就是 Event是Python多線程通信的最簡單的機制之一.一個線程標識一個事件,其他線程一直處於等待狀態。
一個事件對象管理一個內部標示符,這個標示符可以通過set()方法設為True,通過clear()方法重新設為False,wait()方法則使線程一直處於阻塞狀態,直到標示符變為True
也就是說我們可以通過 以上三種方法來多個控制線程的行為。
下面一個簡單的例子,啟動三個子線程,並讓他們一直處於等待狀態,在主線程睡眠5秒后喚醒他們
1 import threading 2 import time 3 4 class TestThread(threading.Thread): 5 def __init__(self, name, event): 6 super(TestThread, self).__init__() 7 self.name = name 8 self.event = event 9 10 def run(self): 11 print 'Thread: ', self.name, ' start at:', time.ctime(time.time()) 12 self.event.wait() 13 print 'Thread: ', self.name, ' finish at:', time.ctime(time.time()) 14 15 def main(): 16 event = threading.Event() 17 threads = [] 18 for i in range(1, 5): 19 threads.append(TestThread(str(i), event)) 20 print 'main thread start at: ', time.ctime(time.time()) 21 event.clear() 22 for thread in threads: 23 thread.start() 24 print 'sleep 5 seconds.......' 25 time.sleep(5) 26 print 'now awake other threads....' 27 event.set() 28 29 main() 30
在列舉一個交通燈例子:
1 __author__ = 'gongxingfa' 2 import threading 3 import random 4 import time 5 6 7 class VehicleThread(threading.Thread): 8 """Class representing a motor vehicle at an intersection""" 9 10 def __init__(self, threadName, event): 11 """Initializes thread""" 12 13 threading.Thread.__init__(self, name=threadName) 14 15 # ensures that each vehicle waits for a green light 16 self.threadEvent = event 17 18 def run(self): 19 """Vehicle waits unless/until light is green""" 20 21 # stagger arrival times 22 time.sleep(random.randrange(1, 10)) 23 24 # prints arrival time of car at intersection 25 print "%s arrived at %s" % \ 26 (self.getName(), time.ctime(time.time())) 27 28 # wait for green light 29 self.threadEvent.wait() 30 31 # displays time that car departs intersection 32 print "%s passes through intersection at %s" % \ 33 (self.getName(), time.ctime(time.time())) 34 35 36 greenLight = threading.Event() 37 vehicleThreads = [] 38 39 # creates and starts ten Vehicle threads 40 for i in range(1, 11): 41 vehicleThreads.append(VehicleThread("Vehicle" + str(i), 42 greenLight)) 43 44 for vehicle in vehicleThreads: 45 vehicle.start() 46 47 while threading.activeCount() > 1: 48 # sets the Event's flag to false -- block all incoming vehicles 49 greenLight.clear() 50 print "RED LIGHT! at", time.ctime(time.time()) 51 time.sleep(3) 52 53 # sets the Event's flag to true -- awaken all waiting vehicles 54 print "GREEN LIGHT! at", time.ctime(time.time()) 55 greenLight.set() 56 time.sleep(1)
從上面的例子看出 threading.Event 相當於貫穿多個線程之間的條件變量,用它能夠很方便的來控制多個線程的行為。