2015-06-24 129 views
0

有人可以帮助我理解在python过程中使用线程的限制。Python - 使用多处理内的线程

我附上了一个我正试图实现的最小工作示例。我的用例要求我提出几个进程,并且在每个进程中我有两个需要通信的线程。但是,即使在下面这个非常简单的例子中,我似乎也会遇到死锁/争论,并且完全不清楚发生了什么问题。

import multiprocessing 
from threading import Thread 
import logging 
import time 
import sys 


def print_all_the_things(char, num): 
    try: 
     while True: 
      sys.stdout.write(char + str(num)) 
    except Exception: 
     logging.exception("Something went wrong") 


class MyProcess(multiprocessing.Process): 
    def __init__(self, num): 
     super(MyProcess, self).__init__() 
     self.num = num 

    def run(self): 
     self.thread1 = Thread(target=print_all_the_things, args=("a", self.num)) 
     self.thread2 = Thread(target=print_all_the_things, args=("b", self.num)) 

     self.thread1.start() 
     self.thread2.start() 

procs = {} 
for a in range(2): 
    procs[a] = MyProcess(a) 
    procs[a].start() 

time.sleep(5) 

for a in range(2): 
    procs[a].join() 

预期输出是标准输出上'a','b','1'和'2'的混杂。然而程序很快就会死锁:

$python mwe.py 
a0a0a0a0a0a0b0b0a0a0b0b0b0b0b0b0b0b0b0b0a0a0a0a0a0a0a0a1a1a2a2a2a2a2b2b2a2 

我应该指出,将MyProcess从线程继承改变成一个工作示例。

我在做什么错?

回答

2

2个进程已启动,它们启动它们的线程,然后它们应该退出 ,因为在run()中没有更多的指令。 但是这些线程仍然处于一种僵尸状态,因为'守护进程' 标志还没有被设置(请参阅Python文档关于此),阻止 这2个进程正常终止。

只是要run()方法没有完成的线程刚开始之后, 例如,你可以等待退出条件:

class MyProcess(multiprocessing.Process): 
    def __init__(self, num, exit_cond): ### new code 
     super(MyProcess, self).__init__() 
     self.num = num 
     self.exit_cond = exit_cond ### new code 

    def run(self): 
     self.thread1 = Thread(target=print_all_the_things, args=("a", self.num)) 
     self.thread2 = Thread(target=print_all_the_things, args=("b", self.num)) 
     self.thread1.daemon=True ### new code 
     self.thread2.daemon=True ### new code 

     self.thread1.start() 
     self.thread2.start() 
     self.exit_cond.wait() ### new code 

procs = {} 
exit_cond = multiprocessing.Event() ### new code 

for a in range(2): 
    procs[a] = MyProcess(a, exit_cond) 
    procs[a].start() 

time.sleep(5) 

exit_cond.set() ### new code 
for a in range(2): 
    procs[a].join() 
+0

此代码的工作非常完美。我一直认为这个过程会在等待线程完成时保持活跃,这让我相信这是一个僵局问题。谢谢你澄清我的误解! – sterne