Condition对象
1.基本介绍
此对象为Python中的threading
模块中的Condition
类. 称之为条件变量. 此对象的主要用途是应对线程同步问题. 首先我们先来看看条件变量的概念.
条件变量:
- 条件变量是线程中的概念, 就是等待某一条件的发生, 和信号一样.
- 条件变量使线程睡眠(blocking)等待某种条件的出现.
- 条件变量是利用线程间共享的全局变量进行同步的一种机制. 主要包括两个动作:
- 一个线程等待"条件变量的条件成立"而挂起;
- 另一个线程使"条件成立"(给出条件成立信号).
- 为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起.
2.应用场景
线程A需要等某个条件才能继续往下执行, 条件不成立, 线程A阻塞等待, 当线程B执行过程中更改条件使之对线程A成立, 就唤醒线程A继续执行.
- 生产者/消费者模型:
3.对象基本方法
acquire(*args)
: 获取锁.这个方法调用底层使用的锁的对应方法.release()
: 释放锁. 这个方法调用底层使用的锁的对应方法.wait(timeout=None)
: 线程挂起直到被其他线程通知或超时. 如果调用此方法的线程没有获得锁, 将会引发RuntimeError
. 调用此方法后, 这个线程将会释放锁, 然后挂起, 直到被其他线程调用notify()
或notify_all()
方法唤醒, 或者超时发生时. 一旦被唤醒, 这个线程将重新获得锁并返回.wait_for(predicate, timeout=None)
:predicate
是一个可调用对象, 返回的结果可被认为是一个布尔值. 线程调用此方法后, 将挂起直到条件计算为真.notify(n=1)
: 默认唤醒一个线程在这个条件上. 可以通过指定n
来指定唤醒的线程数.notify_all()
: 唤醒所有的在此条件上等待的线程.
4.生产者消费者示例
# -*- coding: utf-8 -*-
import threading
import random
import time
class Producer(threading.Thread):
def __init__(self, integers, condition):
threading.Thread.__init__(self)
self.integers = integers
self.condition = condition
def run(self):
while True:
integer = random.randint(0, 256)
self.condition.acquire()
print("condition acquired by {}".format(self.name))
self.integers.append(integer)
print("{} appended to list by {}".format(integer, self.name))
print("condition notified by {}".format(self.name))
self.condition.notify()
print("condition released by {}".format(self.name))
self.condition.release()
time.sleep(1)
class Consumer(threading.Thread):
def __init__(self, integers, condition):
threading.Thread.__init__(self)
self.integers = integers
self.condition = condition
def run(self):
while True:
self.condition.acquire()
print("condition acquired by {}".format(self.name))
while True:
if self.integers:
integer = self.integers.pop()
print("{} popped from list by {}".format(integer, self.name))
break
print("condition wait by {}".format(self.name))
self.condition.wait()
print("condition released by {}".format(self.name))
self.condition.release()
def main():
integers = []
condition = threading.Condition()
t1 = Producer(integers, condition)
t2 = Consumer(integers, condition)
t1.start()
t2.start()
t1.join()
t2.join()
if __name__ == '__main__':
main()