使用Condition实现线程间通信
Condition被称为条件变量,Condition类提供了对复杂线程同步问题的支持,除了提供与Lock类似的acquire()和release()方法外,还提供了wait()、notify()和notify_all()方法,这些方法语法如下:
- wait(timeout=None)。使当前线程释放锁,然后当前线程处于阻塞状态,等待相同条件变量中其他线程唤醒或超时。timeout是设置超时时间。
- notify()。唤醒相同条件变量中的一个线程。
- notify_all()。唤醒相同条件变量中的所有线程。
在一个栈中,通过生产线程(压栈)和消费线程(出栈)来控制压栈和出栈:
import threading
import time
# 创建条件变量对象
condition = threading.Condition()
class Stack:
def __init__(self):
# 堆栈指针初始值为0
self.pointer = 0
# 堆栈有5个数字的空间
self.data = [-1, -1, -1, -1, -1]
# 压栈方法
def push(self, c):
global condition
condition.acquire()
# 堆栈已满,不能压栈
while self.pointer == len(self.data):
# 等待其它线程把数据出栈
condition.wait()
# 通知其他线程把数据出栈
condition.notify()
# 数据压栈
self.data[self.pointer] = c
# 指针向上移动
self.pointer += 1
condition.release()
# 出栈方法
def pop(self):
global condition
condition.acquire()
# 堆栈无数据,不能出栈
while self.pointer == 0:
# 等待其他线程把数据压栈
condition.wait()
# 通知其他线程压栈
condition.notify()
# 指针向下移动
self.pointer -= 1
data = self.data[self.pointer]
condition.release()
# 数据出栈
return data
# 创建堆栈Stack对象
stack = Stack()
# 生产者线程体函数
def producer_thread_body():
global stack # 声明为全局变量
# 产生10个数字
for i in range(0, 10):
# 把数字压栈
stack.push(i)
# 打印数字
print('生产:{0}'.format(i))
# 每产生一个数字线程就睡眠
#time.sleep(1)
# 消费者线程体函数
def consumer_thread_body():
global stack # 声明为全局变量
# 从堆栈中读取数字
for i in range(0, 10):
# 从堆栈中读取数字
x = stack.pop()
# 打印数字
print('消费:{0}'.format(x))
# 每消费一个数字线程就睡眠
#time.sleep(1)
# 主函数
def main():
# 创建生产者线程对象producer
producer = threading.Thread(target=producer_thread_body)
# 启动生产者线程
producer.start()
# 创建消费者线程对象consumer
consumer = threading.Thread(target=consumer_thread_body)
# 启动消费者线程
consumer.start()
if __name__ == '__main__':
main()