2010-09-09 126 views
6

在我的課程中,我運行了4個過程。我怎麼知道孩子進程何時死亡?

from multiprocessing import Process 

    procs = (
      Process(target=ClassOne, name='ClassOne'), 
      Process(target=ClassTwo, name='ClassTwo'), 
      Process(target=ClassThree, name='ClassThree'), 
      Process(target=ClassFour, name='ClassFour'), 
      ) 

    for p in procs: 
     p.daemon = False 
     p.start() 

我希望當我的孩子的過程中一人死亡,所以我可以殺死對方和我自己通知。

回答

3

只要定義的信號處理程序SIGCHLD,檢查由剛剛死去的孩子返回的框架來檢索你需要了解它的信息......並在必要時退出()母公司太:)

+0

@Spi,如果你正在尋找一個Unix特定的解決方案,你應該在問題中指出這一點。 – Constantin 2010-09-09 19:20:05

+0

@Constantin,Win沒有信號?我真的好奇,沒有爭論:) – drAlberT 2010-09-10 08:50:31

+1

Windows有一個C信號API,但本機不使用它們。在Windows中,您可以輕鬆地等待子進程句柄。您只需等待第一個信號發出,然後終止其他信號,然後退出。 – MSalters 2010-09-10 09:17:47

-2

這是一個Windows解決方案。它使用WaitForMultipleObjects API調用。對於Unix os.waitpid可能會完成這項工作。

import multiprocessing as mp 
import ctypes 


SYNCHRONIZE = 0x00100000 
INFINITE = -1 


def mbox(msg): 
    ctypes.windll.user32.MessageBoxW(0, msg, u'spam', 0) 


if __name__ == '__main__': 

    # start 2 processes 
    procs = [mp.Process(target=mbox, args=(msg,)) for msg in u'ab'] 
    for p in procs: 
    p.start() 

    # wait for at least one process to terminate 
    handles = [ 
    ctypes.windll.kernel32.OpenProcess(SYNCHRONIZE, False, p.pid) 
    for p in procs] 
    array_type = ctypes.c_long * len(handles) 
    handle_array = array_type(*handles) 
    ctypes.windll.kernel32.WaitForMultipleObjects(
    len(handles), handle_array, False, INFINITE) 

    # terminate the rest 
    for p in procs: 
    p.terminate() 

    # exit 
    print 'done' 
+1

問題是,waitpid()只接受**一個** pid並且阻塞,直到超時...... WaitForMultipleObjects()完成這項工作,因爲它可以同時處理多個對象......您能否提供POC使用waitpid()? – 2010-09-09 12:40:09

+0

@Spi,正如你明顯發現的那樣,'waitpid'可以用來等待「我不在乎哪一個」孩子死亡。問題是你可能會產生其他孩子,並且'waitpid'也會表示終止信號... – Constantin 2010-09-09 19:17:43

1

最簡單的方法是明確地等待,直到所有進程完成。

while multiprocessing.active_children(): 
    pass 

這不是你想要的事件驅動,但它會在你的例子中完成工作。還請確保你import multiprocessing

+2

當*至少有一個*孩子死亡時,OP不會終止,而不是全部死亡。 – Constantin 2010-09-09 14:07:16

+2

該解決方案將使用一個CPU來忙等待,並且不會像@Constantin指出的那樣解決問題。 – 2012-11-20 13:30:22

3

它可以使用os.waitpid()作爲第一個參數通過-1,並且作爲第二個參數可以使用。

  • 第一個參數表示該請求與當前進程的任何子進程有關。
  • 第二個參數表示它的行爲爲wait()

函數返回一個元組與死亡孩子的pid及其退出代碼。

0

您可能會喜歡在this similar question的回答中查看AutoJoiningProcess類。

如果您準備向代碼添加對gobject(PyGTK的一部分)的依賴性,那麼AutoJoiningProcess將允許您可以偵聽流程完成時發出的信號。然後在那個信號上,你可以迴應你的想法。