1 基本介绍
事件锁是基于条件锁来做的,它与条件锁的区别在于一次只能放行全部,不能放行任意个数的子线程运行。我们可以将事件锁看成红绿灯。当红灯亮时所有线程都处于等待状态;当绿灯亮时所有线程都处于运行状态
2 相关方法
条件锁相关的方法如下:
| 方法 | 描述 |
|---|---|
| threading.Event() | 返回一个事件锁对象 |
| threading.Event().clear() | 使得所有事件都处于暂停状态 |
| threading.Event().set() | 使得所有事件都处于运行状态 |
| threading.Event().is_set() | 判断当前事件状态,运行状态为True,暂停状态为False |
| threading.Event().wait(timeout=None) | 将当前线程设置为“暂停状态,只有该线程接到“绿灯通知”或者超时时间到期之后才会继续运行,在“等待”状态下的线程将允许系统根据策略自行切换到其他线程中运行 |
3 使用示例
下面有2个实例 example 01:
import threading
import time
event = threading.Event()
class Stack:
def __init__(self):
"""
栈
"""
# 栈指针初值为0
self.pointer = 0
self.data = [-1, -1, -1, -1, -1]
def push(self, save_data):
"""
压栈方法
:param save_data:要进行压栈的数据
"""
global event
# 栈已满,不能压栈
while self.pointer == len(self.data):
# 栈已满,生产线程无法添加数据
event.wait()
# 栈已满,通知消费线程取出数据
event.set()
# 数据压栈
self.data[self.pointer] = save_data
# 指针向上移动
self.pointer += 1
def pop(self):
"""
出栈方法
:return: 栈中的数据
"""
global event
# 栈已空,不能出栈
while self.pointer == 0:
# 当栈为空时,消费线程无法消费数据
event.wait()
# 通知生产线程产生数据
event.set()
# 指针向下移动
self.pointer -= 1
# 数据出栈
save_data = self.data[self.pointer]
return save_data
stack = Stack()
def producer_thread_body():
"""
生产者线程体函数
"""
global stack
for num in range(10):
stack.push(num)
print(f'生产数据:{num}')
time.sleep(1)
def consumer_thread_body():
"""
消费者线程体函数
"""
global stack
for _ in range(10):
x = stack.pop()
print(f'消费:{x}')
time.sleep(1)
def main():
t1 = threading.Thread(target=producer_thread_body)
t1.start()
t2 = threading.Thread(target=consumer_thread_body)
t2.start()
if __name__ == '__main__':
main()
result:
生产数据:0
消费:0
生产数据:1
消费:1
生产数据:2
消费:2
生产数据:3
消费:3
生产数据:4消费:4
生产数据:5消费:5
生产数据:6
消费:6
生产数据:7
消费:7
生产数据:8
消费:8
生产数据:9
消费:9
example 02:
import threading
import time
event = threading.Event()
def task1():
i = 0
while True:
if i < 3:
event.clear()
print('阻塞中')
elif i == 4:
event.set()
print('阻塞结束')
time.sleep(1)
if event.is_set():
break
i += 1
def task2():
while True:
print('This is T2')
if event.is_set():
break
time.sleep(2)
if __name__ == '__main__':
t1 = threading.Thread(target=task1)
t2 = threading.Thread(target=task2)
t1.start()
t2.start()
event.wait()
result:
阻塞中
This is T2
阻塞中
This is T2
阻塞中
This is T2
阻塞结束
This is T2
4 with语句
Event()不能使用with语句,只能正常常规操作。 example 02:
import threading
import time
event = threading.Event()
def boss():
print('今天加班5秒钟')
event.clear()
time.sleep(1)
print('时间到了,大家回家吧')
event.set()
def employee():
while True:
if event.is_set():
print('employee:回家了')
break
else:
print('employee:工作中,请勿打扰')
event.wait()
b = threading.Thread(target=boss, )
a = threading.Thread(target=employee, )
b.start()
a.start()
result:
今天加班5秒钟
employee:工作中,请勿打扰
时间到了,大家回家吧
employee:回家了
\