2015-12-04 3 views
1

У меня есть скрипт python, который запускает несколько команд, используя subprocess.Popen. Я добавил обработчик сигнала, который вызывается, если ребенок завершает работу. Я хочу проверить, какой из них закончен. Я могу это сделать, итерации по всем детям:Подпроцесс python: узнать в обработчике сигнала, который заканчивается дочерним

#!/usr/bin/env python 
import subprocess 
import signal 

procs = [] 

def signal_handler(signum, frame): 
    for proc in procs: 
     proc.poll() 
     if proc.returncode is not None: 
      print "%s returned %s" % (proc.pid, proc.returncode) 
      procs.remove(proc) 

def main(): 
    signal.signal(signal.SIGCHLD, signal_handler) 
    procs.append(subprocess.Popen(["/bin/sleep", "2"])) 
    procs.append(subprocess.Popen(["/bin/sleep","5"])) 
    # wait so the main process does not terminate immediately 
    procs[1].wait() 

if __name__ == "__main__": 
    main() 

Я хотел бы избежать запроса всех подпроцессов. Есть ли способ определить в обработчике сигнала, который ребенок прекратил?

ответ

1

Вы можете добиться аналогичного результата, используя multiprocessing. Вместо этого вы можете использовать пакет threading, если вы не хотите создавать дополнительные процессы. Он имеет практически такой же интерфейс. В принципе, каждый вызов subprocess происходит в новом процессе, который затем запускает ваши процессы sleep.

import subprocess 
import multiprocessing 

def callback(result): 
    # do something with result 
    pid, returncode = result 
    print pid, returncode 


def call_process(cmd): 
    p = subprocess.Popen(cmd) 
    p.wait() 
    return p.pid, p.returncode 


def main(): 
    pool = multiprocessing.Pool() 
    pool.apply_async(call_process, [["/bin/sleep", "2"]], callback=callback) 
    pool.apply_async(call_process, [["/bin/sleep", "5"]], callback=callback) 
    pool.close() 
    pool.join() 


main() 
+0

Этот подход имеет две проблемы: 1. Без обмена данными между процессами у меня нет информации об этих двух подпроцессах. 2. Я должен знать, сколько процессов я хочу начать, потому что пул запускает только определенное количество рабочих одновременно. – morxa

+0

@morxa Вы можете обмениваться данными между процессами с многопроцессорной обработкой. Какие данные вам необходимо предоставить? «Пул» - это просто самый простой способ запуска нескольких процессов. По умолчанию он уменьшает количество процессов до количества ядер, которые у вас есть, что обычно является хорошей идеей. Но если вы хотите больше контролировать его, вы можете просто использовать «multiprocessing.Process» и создать столько, сколько хотите. –

Смежные вопросы