我在同步2个线程方面遇到了很大困难。每个线程都取决于另一个线程的结果。我们说我有以下代码:
from multiprocessing import Condition, Process
import time
def B_producer(new_A,new_B):
while True:
with new_A:
new_A.wait()
with new_B:
print 'B',
new_B.notify_all()
if __name__=='__main__':
new_A = Condition()
new_B = Condition()
B_producer = Process(target=B_producer, args=(new_A,new_B))
B_producer.start()
time.sleep(2)
while True:
with new_A:
print 'A',
new_A.notify()
with new_B:
new_B.wait()
我希望看到的输出如下:A B A B A B A B A B ...,以便主线程通过生成' A'开始,而另一个正在等待。一旦'A'已经制作完毕,它等待着B'。同时,次要线程则相反。不能重复写字母。不幸的是,我找不到让它按预期工作的方法。
编辑:鉴于第一个答案中的讨论,我更改了代码,以便更清楚地说明程序进入死锁并且永远不会终止:
from multiprocessing import Condition, Process
import time
def B_producer(new_A,new_B):
while True:
with new_A:
new_A.wait()
with new_B:
#do something
new_B.notify_all()
if __name__=='__main__':
new_A = Condition()
new_B = Condition()
B_producer = Process(target=B_producer, args=(new_A,new_B))
B_producer.start()
time.sleep(2)
count = 0
while True:
with new_A:
#do something
new_A.notify()
with new_B:
new_B.wait()
count += 1
if count == 1000000:
break
B_producer.terminate()
sys.stdout.write('end')
sys.stdout.flush()
答案 0 :(得分:2)
您的代码有效,唯一的问题是您遇到print "A/B",
的一些问题。这里的问题是print
之后的逗号。它可以防止打印后换行,但print语句无法更新控制台上已写入的行,只能写入单行。因此,它会将所有内容存储在缓冲区中,直到您使用换行符执行print
,然后写入整行。
你可以做两件事:
print
之后的逗号(这将导致每个字母在单独的行中打印)。sys.stdout.write('A/B ')
后跟sys.stdout.flush()
(以保持输出更新)。别忘了import sys
。答案 1 :(得分:0)
我想我得到了一个解决方案,即使可能有一个更简单的解决方案。我为它添加了一个启动条件,以避免在B_producer准备就绪之前启动主循环并等待主线程完成其中。我还必须添加一个额外的锁来防止竞争条件达到new_A条件。
def B_producer(new_A,new_B,synch,start):
synch.acquire()
while True:
with new_A:
synch.release()
with start:
start.notify()
new_A.wait()
with new_B:
#Do something
synch.acquire()
new_B.notify()
if __name__=='__main__':
new_A = Condition()
new_B = Condition()
start = Condition()
synch = Lock()
B_producer = Process(target=B_producer, args=(new_A,new_B,synch,start))
with start:
B_producer.start()
start.wait()
count = 0
synch.acquire()
while True:
new_A.acquire()
synch.release()
#Do something
with new_B:
new_A.notify()
new_A.release()
new_B.wait()
synch.acquire()
count += 1
if count%100000 == 0:
break
B_producer.terminate()
print 'end'
如果有人找到更好/更简单的解决方案,请发布!
由于