python thread-condition()简单示例
#!/usr/bin/env python # -*-coding:utf-8-*- import threading import time condition = threading.Condition() products = 0 class Producer(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): global condition, products while True: if condition.acquire(): if products < 10: products += 1 print("Producer(%s):deliver one, now products:%s" % (self.name, products)) condition.notify() else: print ("Producer(%s):already 10, stop deliver, now products:%s" %(self.name, products)) condition.wait() condition.release() time.sleep(2) class Consumer(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): global condition, products while True: if condition.acquire(): if products > 1: products -= 1 print("Consumer(%s):consume one, now products:%s" % (self.name, products)) condition.notify() else: print("Consumer(%s):only 1, stop consume, products:%s" %(self.name, products)) condition.wait() condition.release() time.sleep(1) if __name__ == "__main__": for q in range(0, 10): p = Producer() p.start() for i in range(0,2): c = Consumer() c.start()
执行结果:
Producer(Thread-1):deliver one, now products:1 Producer(Thread-2):deliver one, now products:2 Producer(Thread-3):deliver one, now products:3 Producer(Thread-4):deliver one, now products:4 Producer(Thread-5):deliver one, now products:5 Producer(Thread-6):deliver one, now products:6 Producer(Thread-7):deliver one, now products:7 Producer(Thread-8):deliver one, now products:8 Producer(Thread-9):deliver one, now products:9 Producer(Thread-10):deliver one, now products:10 Consumer(Thread-11):consume one, now products:9 Consumer(Thread-12):consume one, now products:8 Consumer(Thread-12):consume one, now products:7 Consumer(Thread-11):consume one, now products:6 Producer(Thread-10):deliver one, now products:7 Producer(Thread-7):deliver one, now products:8 Producer(Thread-4):deliver one, now products:9 Producer(Thread-3):deliver one, now products:10 Producer(Thread-2):already 10, stop deliver, now products:10 Producer(Thread-8):already 10, stop deliver, now products:10 Producer(Thread-6):already 10, stop deliver, now products:10 Producer(Thread-9):already 10, stop deliver, now products:10 Producer(Thread-5):already 10, stop deliver, now products:10 Producer(Thread-1):already 10, stop deliver, now products:10 Consumer(Thread-11):consume one, now products:9 Consumer(Thread-12):consume one, now products:8 Consumer(Thread-11):consume one, now products:7 Consumer(Thread-12):consume one, now products:6 Producer(Thread-4):deliver one, now products:7 Producer(Thread-3):deliver one, now products:8 Producer(Thread-10):deliver one, now products:9 Producer(Thread-7):deliver one, now products:10 Producer(Thread-2):already 10, stop deliver, now products:10 Producer(Thread-8):already 10, stop deliver, now products:10 Consumer(Thread-12):consume one, now products:9 Consumer(Thread-11):consume one, now products:8 Producer(Thread-9):deliver one, now products:9 Producer(Thread-6):deliver one, now products:10 Consumer(Thread-11):consume one, now products:9 Consumer(Thread-12):consume one, now products:8 Producer(Thread-3):deliver one, now products:9 Producer(Thread-1):deliver one, now products:10 Producer(Thread-10):already 10, stop deliver, now products:10 Producer(Thread-5):already 10, stop deliver, now products:10 Producer(Thread-7):already 10, stop deliver, now products:10 Producer(Thread-4):already 10, stop deliver, now products:10 Producer(Thread-8):already 10, stop deliver, now products:10 Producer(Thread-2):already 10, stop deliver, now products:10 Consumer(Thread-12):consume one, now products:9 Consumer(Thread-11):consume one, now products:8 Producer(Thread-6):deliver one, now products:9 Producer(Thread-9):deliver one, now products:10 Consumer(Thread-12):consume one, now products:9 Consumer(Thread-11):consume one, now products:8
......
Condition类:条件变量对象能让一个线程停下来,等待其它线程满足了某个“条件”。如,状态的改变或值的改变。
- acquire 给线程上锁
- wait wait方法释放当前线程占用的锁,同时挂起线程,直至被唤醒或超时(需timeout参数)。当线程被唤醒并重新占有锁的时候,程序才会继续执行下去。
- notify 唤醒一个挂起的线程(如果存在挂起的线程)。注:notify()方法不会释放所占用的锁。
- notifyall 调用这个方法将通知等待池中所有线程,这些线程都将进入锁定池尝试获得锁定。此方法不会释放锁定。使用前线程必须已获得锁定,否则将抛出异常。
比较经典的例子是下面这个生产者与消费者的例子,这个例子网上一搜到处都是,这里简单解释一下这段代码的意义,代码中写了两个类,Consumer和Producer,分别继承了Thread类,我们分别初始化这两个类获得了c和p对象,并启动这两个线程。则这两个线程去执行run方法(这里与Thread类内部的调度有关),定义了producer全局变量和condition对象为全局变量,当producer不大于1时,消费者线程被condition对象阻塞,不能继续消费(这里是不再递减),当producer不小于10时,生产者线程被condition对象阻塞,不再生产(这里是不再累加).