线程 通讯

Condition

Condition(条件变量)一般与一个锁关联。须要在多个Contidion中共享一个锁时,能够传递一个Lock/RLock实例给构造方法,不然它将本身生成一个RLock实例。 html

能够认为,除了Lock带有的锁定池外,Condition还包含一个等待池,池中的线程处于状态图中的等待阻塞状态,直到另外一个线程调用notify()/notifyAll()通知;获得通知后线程进入锁定池等待锁定。ui

构造方法:
Condition([lock/rlock])spa

实例方法:
acquire([timeout])/release(): 调用关联的锁的相应方法。
wait([timeout]): 调用这个方法将使线程进入Condition的等待池等待通知,并释放锁。使用前线程必须已得到锁定,不然将抛出异常。
notify(): 调用这个方法将从等待池挑选一个线程并通知,收到通知的线程将自动调用acquire()尝试得到锁定(进入锁定池);其余线程仍然在等待池中。调用这个方法不会释放锁定。使用前线程必须已得到锁定,不然将抛出异常。
notifyAll(): 调用这个方法将通知等待池中全部的线程,这些线程都将进入锁定池尝试得到锁定。调用这个方法不会释放锁定。使用前线程必须已得到锁定,不然将抛出异常。线程

例子是很常见的生产者/消费者模式:code

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# encoding: UTF-8
import threading
import time
 
# 商品
product = None
# 条件变量
con = threading.Condition()
 
# 生产者方法
def produce():
     global product
    
     if con.acquire():
         while True :
             if product is None :
                 print 'produce...'
                 product = 'anything'
                
                 # 通知消费者,商品已经生产
                 con.notify()
            
             # 等待通知
             con.wait()
             time.sleep( 2 )
 
# 消费者方法
def consume():
     global product
    
     if con.acquire():
         while True :
             if product is not None :
                 print 'consume...'
                 product = None
                
                 # 通知生产者,商品已经没了
                 con.notify()
            
             # 等待通知
             con.wait()
             time.sleep( 2 )
 
t1 = threading.Thread(target = produce)
t2 = threading.Thread(target = consume)
t2.start()
t1.start()