gpt4 book ai didi

python - 消费者/生产者不等待事件

转载 作者:太空宇宙 更新时间:2023-11-03 15:09:48 25 4
gpt4 key购买 nike

我想写一个程序生产者/消费者,在这个程序中我有一个 parent 和一个儿子, parent 用一些鱼填充一个共享变量并向儿子发送通知。儿子开始进食,如果没有鱼,就通知 parent 。我试过这段代码,但它不起作用:

import threading
import time

NUM_FISH = 13

mutex = threading.Lock()
mutParent = threading.Event()
mutSon = threading.Event()

fish = NUM_FISH

def set(fish1):
global fish
fish = fish1

def get():
return fish

def parent(mutParent, mutSon):
while True:
mutex.acquire()
mutParent.wait()
time.sleep(0.5)
try:
set(NUM_FISH)
print " + parent brings %d fish\n" % fish
mutex.release()
mutSon.set()
except:
print "Exception"
mutex.release()

def son(id, mutParent, mutSon):
while True:
mutex.acquire()
mutSon.wait()
fish = get() - 1
set(fish)
time.sleep(0.5)
try:
if fish > 0 :
print " - Son %d eats (dish: %d fish)\n" % (id, fish)
mutex.release()
else:
print " - Son %d eats (dish: %d fish) and screams\n\n" % (id, fish)
mutex.release()
mutParent.set()
except:
print "Exception"
mutex.release()

print "\n + intitial dish: %d fish\n\n" % fish

mutSon.set()
t2 = threading.Thread(target=son, args=(1, mutParent, mutSon))
t2.start()

t1 = threading.Thread(target=parent, args = (mutParent, mutSon))
t1.start()

t2.join()
t1.join()

这是我的输出:

myself@ubuntu:~/Desktop$ python a.py

+ intitial dish: 13 fish


- Son 1 eats (dish: 12 fish)

- Son 1 eats (dish: 11 fish)

- Son 1 eats (dish: 10 fish)

- Son 1 eats (dish: 9 fish)

- Son 1 eats (dish: 8 fish)

- Son 1 eats (dish: 7 fish)

- Son 1 eats (dish: 6 fish)

- Son 1 eats (dish: 5 fish)

- Son 1 eats (dish: 4 fish)

- Son 1 eats (dish: 3 fish)

- Son 1 eats (dish: 2 fish)

- Son 1 eats (dish: 1 fish)

- Son 1 eats (dish: 0 fish) and screams


- Son 1 eats (dish: -1 fish) and screams


- Son 1 eats (dish: -2 fish) and screams


- Son 1 eats (dish: -3 fish) and screams


- Son 1 eats (dish: -4 fish) and screams


- Son 1 eats (dish: -5 fish) and screams


+ parent brings 13 fish

+ parent brings 13 fish

最佳答案

好的,这里可以改变三件事:

  1. 这是一种装饰品。使用 with mutex: 而不是所有的 mutex.acquire()mutex.release(),因为这些东西会自动发生,使得代码更短,更不容易出错。
  2. 在获取mutex 之前,您应该等待您的事件。否则一个线程将获得互斥量,然后开始等待它的条件变量,但是,应该设置它的线程无法获得mutex,所以一切都停止了。请注意,当有多个儿子或 parent 时,必须在锁定 mutex 后重新检查事件。这是因为在等待事件之后,事件可能在获取 mutex 之前被清除。
  3. 等待一个事件后,你应该对事件采取行动,然后清除它。否则,当子线程设置事件时,父线程被唤醒并进行处理。但是,由于事件仍然设置,如果 parent 再次醒来,它会再次进行,给出双亲线(和双子线)。

进行这些调整后得到以下代码:

def parent(id, mutParent, mutSon):
while True:
mutParent.wait()
with mutex:
if not mutParent.is_set():
continue
time.sleep(0.5)
try:
set(NUM_FISH)
print " + Parent %d brings %d fish\n" % (id, fish)
mutParent.clear()
mutSon.set()
except:
print "Exception"

def son(id, mutParent, mutSon):
while True:
mutSon.wait()
with mutex:
if not mutSon.is_set():
continue
fish = get() - 1
set(fish)
time.sleep(0.5)
try:
if fish > 0:
print " - Son %d eats (dish: %d fish)\n" % (id, fish)
else:
print " - Son %d eats (dish: %d fish) and screams\n\n" % (id, fish)
mutSon.clear()
mutParent.set()
except:
print "Exception"

我还没有设法打破这一点(与多个儿子或 parent 一起工作),所以我认为它是正确的,但是对这一点的任何更正都是最受欢迎的(因为这是多线程,奇怪的事情存在于并行的阴影中).

关于python - 消费者/生产者不等待事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28307892/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com