2016-02-10 63 views
2

我用信號函數來殺死在MUL-處理程序的所有子過程,則代碼如吹塑,另存爲一個名爲mul_process.py文件:通過信號殺死子進程,但位置會影響?

import time 
import os 
import signal 
from multiprocessing import Process 

processes = [] 

def fun(x): 
    print 'current sub-process pid is %s' % os.getpid() 
    while True: 
     print 'args is %s' % x 
     time.sleep(100) 

def term(sig_num, frame): 
    print 'terminate process %d' % os.getpid() 
    for p in processes: 
     print p.pid 
    try: 
     for p in processes: 
      print 'process %d terminate' % p.pid 
      p.terminate() 
      p.join() 
    except Exception as e: 
     print str(e) 

if __name__ == '__main__': 
    print 'current main-process pid is %s' % os.getpid() 
    for i in range(3): 
     t = Process(target=fun, args=(str(i),)) 
     t.start() 
     processes.append(t) 
    signal.signal(signal.SIGTERM, term) 
    try: 
     for p in processes: 
      p.join() 
    except Exception as e: 
     print str(e) 

使用「蟒mul_process.py」來在Ubuntu 10.04.4和Python 2.6上啓動程序,當它開始運行時,在另一個選項卡中,我使用kill -15和主進程pid發送信號SIGTERM來終止所有進程,當主進程接收到SIGTERM信號時,它在終止所有子進程後退出,但是當我用子進程pid使用kill -15時,它不起作用,程序仍然活着並像以前一樣運行,並且不打印在函數術語中定義的句子,似乎子進程沒有收到SIGTERM。據我所知,子進程會繼承信號h安德勒,但它不起作用,這是第一個問題。

然後我招行 'signal.signal(signal.SIGTERM,期限)' 到位置行後 '如果 ==' 主要 ':',像這樣:

if __name__ == '__main__': 
    signal.signal(signal.SIGTERM, term) 
    print 'current main-process pid is %s' % os.getpid() 
    for i in range(3): 
     t = Process(target=fun, args=(str(i),)) 
     t.start() 
     processes.append(t) 
    try: 
     for p in processes: 
      p.join() 
    except Exception as e: 
     print str(e) 

啓動程序,並用主進程pid使用kill -15發送信號SIGTERM,程序接收信號並調用函數項,但也不殺死任何子進程並退出自身,這是第二個問題。

回答

1

程序中的幾個問題 - 同意子進程會繼承第二個代碼片段中的信號處理程序,但是不會共享全局變量「進程」列表。所以只有主進程才能提供進程列表。 「進程」將是其他子進程的空列表。 您可以使用隊列或管道類型的機制將進程列表傳遞給子進程。但它會帶來另一個問題

您終止process1和process1的處理程序嘗試終止process2到process4。

現在處理2也具有相同的處理,

So Process 2 handler again try to terminate all other process

,這將推動你的程序進入無限循環。

+0

謝謝你的回答。我再次嘗試第二個代碼,當我用子進程pid殺掉-15時,我打印全局變量'processes',就像你說的那樣,它是一個空列表,然後用主進程pid殺掉-15,全局變量'進程'workds,但我發現當在函數術語中調用p.terminate()時,os會將信號SIGTERM發送到子進程,因爲繼承了相同的信號處理程序,但全局變量'processes'是空的列表,所以程序將不會運行,因爲我 – tourun

+0

但我仍然混淆了我寫下行'signal.signal(signal.SIGTERM,term)'的位置,程序將顯示不同的外觀 – tourun

+0

@tourun You應該在任何地方,但在開始新流程之前進行。 當我們創建一個子進程時,它會得到父進程地址空間的精確副本,所以在創建子進程時,父進程和子進程都會有獨立的地址空間,但內容相同。 – AlokThakur