Python多线程-Event(事件对象)

python

Event

事件对象管理一个内部标志,通过set()方法将其设置为True,并使用clear()方法将其设置为Falsewait()方法阻塞,直到标志为True。该标志初始为False

方法:
is_set()

当且仅当内部标志为True时返回True

set()

将内部标志设置为True。所有等待它成为True的线程都被唤醒。当标志保持在True的状态时,线程调用wait()是不会阻塞的。

clear()

将内部标志重置为False。随后,调用wait()的线程将阻塞,直到另一个线程调用set()将内部标志重新设置为True

wait(timeout=None)

阻塞直到内部标志为真。如果内部标志在wait()方法调用时为True,则立即返回。否则,则阻塞,直到另一个线程调用set()将标志设置为True,或发生超时。

该方法总是返回True,除非设置了timeout并发生超时。

生产者与消费之--Event版

# -*- coding:utf-8 -*-

import threading

import time

import queue

event = threading.Event()

goods = queue.Queue(5)

num = 0

class Producer(threading.Thread):

def run(self):

global num

while True:

if goods.empty():

event.clear()

for _ in range(5):

goods.put('商品-' + str(num))

print('生产了商品-{0}.'.format(str(num)))

num += 1

time.sleep(1)

event.set()

class Customer(threading.Thread):

def __init__(self, *args, **kwargs):

super().__init__(*args, **kwargs)

self.money = 7

def run(self):

while self.money:

event.wait()

self.money -= 1

print('{0} 买了一个{1}.'.format(

threading.current_thread().name, goods.get()))

time.sleep(1)

print('{0}没钱了,回家.'.format(threading.current_thread().name))

if __name__ == '__main__':

p = Producer(daemon=True)

c1 = Customer(name='Alice')

c2 = Customer(name='Bob')

c2.start()

p.start()

c1.start()

c1.join()

c2.join()

运行结果:

生产了商品-0.

生产了商品-1.

生产了商品-2.

生产了商品-3.

生产了商品-4.

Alice 买了一个商品-0.

Bob 买了一个商品-1.

Alice 买了一个商品-2.

Bob 买了一个商品-3.

Alice 买了一个商品-4.

生产了商品-5.

生产了商品-6.

生产了商品-7.

生产了商品-8.

生产了商品-9.

Alice 买了一个商品-5.

Bob 买了一个商品-6.

Alice 买了一个商品-7.

Bob 买了一个商品-8.

生产了商品-10.

Alice 买了一个商品-9.

生产了商品-11.

生产了商品-12.

生产了商品-13.

生产了商品-14.

Alice 买了一个商品-10.

Bob 买了一个商品-11.

Alice没钱了,回家.

Bob 买了一个商品-12.

Bob 买了一个商品-13.

Bob没钱了,回家.

这里会出现一种特殊情况,当消费者线程较多时会大量出现:

生产了商品-0.

生产了商品-1.

生产了商品-2.

生产了商品-3.

生产了商品-4.

Bob 买了一个商品-0.

Alice 买了一个商品-1.

Bob 买了一个商品-2.

Alice 买了一个商品-3.

Bob 买了一个商品-4.

生产了商品-5. # !!!!!

Alice 买了一个商品-5. # !!!!!

生产了商品-6.

生产了商品-7.

生产了商品-8.

生产了商品-9.

Bob 买了一个商品-6.

Alice 买了一个商品-7.

Alice 买了一个商品-8.

Bob 买了一个商品-9.

生产了商品-10.

生产了商品-11.

生产了商品-12.

生产了商品-13.

生产了商品-14.

Alice 买了一个商品-10.

Bob 买了一个商品-11.

Bob 买了一个商品-12.

Alice 买了一个商品-13.

Bob没钱了,回家.

Alice没钱了,回家.

这是因为生产者在轮询检查商品是否为空会有很小的延迟,在这个延迟中有消费者线程正好跑过了wait()方法,而阻塞在了商品获取这里(商品使用了队列,队列是线程安全的,当队列为空时,get()方法会阻塞),所以当生产者开始执行的时候,这个消费者因为商品队列里有数据就被立即唤醒了。

以上是 Python多线程-Event(事件对象) 的全部内容, 来源链接: utcz.com/z/387962.html

回到顶部