2015-06-24 181 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