Один питон многопроцессных ошибок - PullRequest
0 голосов
/ 27 октября 2010

У меня есть одно многопроцессорное демо, и я столкнулся с некоторыми проблемами с ним.Исследовал на ночь, я не могу решить причину.Кто-нибудь может мне помочь?

Я хочу, чтобы один родительский процесс выступал в роли производителя, когда приходят задачи, родитель может разветвлять некоторых потомков, чтобы использовать эти задачи.Родитель следит за ребенком, если любой из них выходит за исключением, он может быть перезапущен родителем.


#!/usr/bin/env python
# -*- coding: utf-8 -*-

from multiprocessing import Process, Queue from Queue import Empty import sys, signal, os, random, time import traceback

child_process = []
child_process_num = 4
queue = Queue(0)

def work(queue):
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    signal.signal(signal.SIGTERM, signal.SIG_DFL)
    signal.signal(signal.SIGCHLD, signal.SIG_DFL)

    time.sleep(10) #demo sleep 

def kill_child_processes(signum, frame):
    #terminate all children
    pass

def restart_child_process(signum, frame):
    global child_process

    for i in xrange(len(child_process)):
        child = child_process[i]

        try:
            if child.is_alive():
                continue
        except OSError, e:
            pass

        child.join() #join this process to make sure there is no zombie process

        new_child = Process(target=work, args=(queue,))
        new_child.start()
        child_process[i] = new_child #restart one new process

        child = None
        return

if __name__ == '__main__':
    reload(sys)
    sys.setdefaultencoding("utf-8")

    for i in xrange(child_process_num):
        child = Process(target=work, args=(queue,))
        child.start()
        child_process.append(child)

    signal.signal(signal.SIGINT, kill_child_processes)
    signal.signal(signal.SIGTERM, kill_child_processes) #hook the SIGTERM
    signal.signal(signal.SIGCHLD, restart_child_process)
    signal.signal(signal.SIGPIPE, signal.SIG_DFL)

При запуске этой программы будут возникать следующие ошибки:

</p> <pre> Error in atexit._run_exitfuncs: Error in sys.exitfunc: Traceback (most recent call last): File "/usr/local/python/lib/python2.6/atexit.py", line 30, in _run_exitfuncs traceback.print_exc() File "/usr/local/python/lib/python2.6/traceback.py", line 227, in print_exc print_exception(etype, value, tb, limit, file) File "/usr/local/python/lib/python2.6/traceback.py", line 124, in print_exception _print(file, 'Traceback (most recent call last):') File "/usr/local/python/lib/python2.6/traceback.py", line 12, in _print def _print(file, str='', terminator='\n'): File "test.py", line 42, in restart_child_process new_child.start() File "/usr/local/python/lib/python2.6/multiprocessing/process.py", line 99, in start _cleanup() File "/usr/local/python/lib/python2.6/multiprocessing/process.py", line 53, in _cleanup if p._popen.poll() is not None: File "/usr/local/python/lib/python2.6/multiprocessing/forking.py", line 106, in poll pid, sts = os.waitpid(self.pid, flag) OSError: [Errno 10] No child processes

Если я отправлю сигнал одному ребенку: kill –SIGINT {child_pid}, я получу:

</p> <pre> [root@mail1 mail]# kill -SIGINT 32545 [root@mail1 mail]# Error in atexit._run_exitfuncs: Traceback (most recent call last): File "/usr/local/python/lib/python2.6/atexit.py", line 24, in _run_exitfuncs func(*targs, **kargs) File "/usr/local/python/lib/python2.6/multiprocessing/util.py", line 269, in _exit_function p.join() File "/usr/local/python/lib/python2.6/multiprocessing/process.py", line 119, in join res = self._popen.wait(timeout) File "/usr/local/python/lib/python2.6/multiprocessing/forking.py", line 117, in wait return self.poll(0) File "/usr/local/python/lib/python2.6/multiprocessing/forking.py", line 106, in poll pid, sts = os.waitpid(self.pid, flag) OSError: [Errno 4] Interrupted system call Error in sys.exitfunc: Traceback (most recent call last): File "/usr/local/python/lib/python2.6/atexit.py", line 24, in _run_exitfuncs func(*targs, **kargs) File "/usr/local/python/lib/python2.6/multiprocessing/util.py", line 269, in _exit_function p.join() File "/usr/local/python/lib/python2.6/multiprocessing/process.py", line 119, in join res = self._popen.wait(timeout) File "/usr/local/python/lib/python2.6/multiprocessing/forking.py", line 117, in wait return self.poll(0) File "/usr/local/python/lib/python2.6/multiprocessing/forking.py", line 106, in poll pid, sts = os.waitpid(self.pid, flag) OSError: [Errno 4] Interrupted system call

1 Ответ

1 голос
/ 08 декабря 2010

Основной процесс ожидает завершения всех дочерних процессов, прежде чем завершится сам, поэтому существует блокирующий вызов (т. Е. Wait4), зарегистрированный как дескрипторы at_exit.Сигнал, который вы послали, прерывает этот блокирующий вызов, таким образом, трассировка стека.

Что мне не ясно, так это то, что если сигнал, отправленный потомку, будет перенаправлен на родительский процесс, который затем прервет этот вызов wait4.Это связано с поведением групп процессов Unix.

...