Event是threading模块下一个简单的类,主要用于线程间通信。
Event本身管理一个信号标志,信号标志为真时,线程被唤醒,信号标志为假时,通常搭配wait()方法阻塞线程。
Evevt类提供的方法:
- is_set() :该方法返回Event的信号标志是否为True。
- set() :将信号标志设置为True,并唤醒所有处于等待状态的线程。
- clear() :将信号标志设置为False,通常接下来会调用wait()方法阻塞当前线程。
- wait(timeout) :阻塞当前线程。
示例1:
import threading
from time import sleep
event = threading.Event()
def info():
print('%s is ready to do.' % (threading.currentThread().name))
event.wait()
print('%s is running.' % (threading.currentThread().name))
threading.Thread(target=info,name=('小白')).start()
threading.Thread(target=info,name=('小黑')).start()
sleep(2)
print('%s is running.' % (threading.currentThread().name))
event.set()
运行结果:
小白 is ready to do.
小黑 is ready to do.
MainThread is running.
小白 is running.
小黑 is running.
<分析>
这个例子十分简单,只用到了Event类的wait()方法和set()方法,可以看到两条线程均在event.wait()处被阻塞,之后一直到主线程运行到event.set()处才又被重新唤醒。
示例2:
用Event类实现生产者消费者问题
问题:
假设有一群生产者(Producer)和一群消费者(Consumer)通过一个市场来交互产品。生产者的”策略“是如果市场上剩余的产品少于10个,那么就生产3个产品放到市场上;而消费者的”策略“是如果市场上剩余产品的数量多于7个,那么就消费1个产品。
代码:
import threading
from time import sleep
product = 10
event1 = threading.Event()
event2 = threading.Event()
class Producer(threading.Thread):
def __init__(self,name):
super().__init__()
self.name = name
self.lock = threading.RLock()
def run(self):
global product
while True:
if self.lock.acquire():
if product >= 10:
event1.clear()
event2.set()
event1.wait()
else:
event1.set()
product += 3
message = self.name + " produced 3 products."
print(message)
self.lock.release()
sleep(1)
class Consumer(threading.Thread):
def __init__(self,name):
super().__init__()
self.name = name
self.lock = threading.RLock()
def run(self):
global product
while True:
if self.lock.acquire():
if product <= 7:
event1.set()
event2.clear()
event2.wait()
else:
event2.set()
product -= 1
message = self.name + " consumed 1 products."
print(message)
self.lock.release()
sleep(1)
def main():
for i in range(2):
p = Producer('Producer-%d'%i)
p.start()
for i in range(3):
c = Consumer('Consumer-%d'%i)
c.start()
if __name__ == '__main__':
main()
运行结果:
Consumer-0 consumed 1 products.
Consumer-1 consumed 1 products.
Consumer-2 consumed 1 products.
Producer-1 produced 3 products.
Consumer-0 consumed 1 products.
Consumer-2 consumed 1 products.
Consumer-1 consumed 1 products.
Producer-1 produced 3 products.
Consumer-1 consumed 1 products.
Consumer-2 consumed 1 products.
Consumer-0 consumed 1 products.
Producer-0 produced 3 products.
......
<分析>
这个示例与我上一盘用Condition类实现生产者消费者问题的思路是差不多的,鉴于上一篇已有过详解,这里就略过。无非是用
Event+Lock 代替了 condition 的功能。