2013-11-15 7 views
4

동료가 자신이 작업중인 데몬 스크립트로 인해 발생한 문제에 대해 도움을 요청했습니다. 그는 내가 다음과 같은 다섯 개 가지 라인을 재현하기 위해 관리하는 multiprocessing.Manager을 포함하는 이상한 오류를 가지고 있었다 : CentOS는 6 리눅스와 파이썬 2.6에서 실행Python 다중 처리. 이상한 동작을 생성하는 관리자 및 os.fork

import multiprocessing, os, sys 
mgr = multiprocessing.Manager() 
pid = os.fork() 
if pid > 0: 
    sys.exit(0) 

, 나는 다음과 같은 오류 얻을 :

Traceback (most recent call last): 
    File "/usr/lib64/python2.6/multiprocessing/util.py", line 235, in _run_finalizers 
    finalizer() 
    File "/usr/lib64/python2.6/multiprocessing/util.py", line 174, in __call__ 
    res = self._callback(*self._args, **self._kwargs) 
    File "/usr/lib64/python2.6/multiprocessing/managers.py", line 576, in _finalize_manager 
    if process.is_alive(): 
    File "/usr/lib64/python2.6/multiprocessing/process.py", line 129, in is_alive 
    assert self._parent_pid == os.getpid(), 'can only test a child process' 
AssertionError: can only test a child process 
Error in atexit._run_exitfuncs: 
Traceback (most recent call last): 
    File "/usr/lib64/python2.6/atexit.py", line 24, in _run_exitfuncs 
    func(*targs, **kargs) 
    File "/usr/lib64/python2.6/multiprocessing/util.py", line 269, in _exit_function 
    p.join() 
    File "/usr/lib64/python2.6/multiprocessing/process.py", line 117, in join 
    assert self._parent_pid == os.getpid(), 'can only join a child process' 
AssertionError: can only join a child process 
Error in sys.exitfunc: 
Traceback (most recent call last): 
    File "/usr/lib64/python2.6/atexit.py", line 24, in _run_exitfuncs 
    func(*targs, **kargs) 
    File "/usr/lib64/python2.6/multiprocessing/util.py", line 269, in _exit_function 
    p.join() 
    File "/usr/lib64/python2.6/multiprocessing/process.py", line 117, in join 
    assert self._parent_pid == os.getpid(), 'can only join a child process' 
AssertionError: can only join a child process 

os.fork와 multiprocessing.Manager 사이의 상호 작용으로 인해 오류가 발생한 것으로 의심되며 os.fork 대신 새 프로세스를 작성하기 위해 다중 처리 모듈을 사용해야합니다. 누구든지이 사실을 확인하거나 어떤 일이 벌어지고 있는지 설명 할 수 있습니까? 내 직감이 정확하다면 왜 os.fork를 사용하는 것이 잘못된 곳입니까?

+1

'Manager '는 항상 공유 메모리를 처리하는 새로운 프로세스를 생성하므로 약간의 상호 작용이있는 것으로 보입니다. 지금 당장이 일이 왜 일어나는지와'os.fork'를 사용하여 이것을 고치는 법을 정확히 말할 수는 없습니다. 나는'os.fork'를 사용하는 것이 실제로는 * 저수준 *이기 때문에 피해야한다는 것에 동의해야합니다. 대신에'multiprocessing'을 사용하는 방법이 있어야합니다. – Bakuriu

답변

2

문제는 Manager입니다. 프로세스를 만들고 그 프로세스를 중지하려고 시도합니다 (sys.exit). 포크 동안 프로세스의 메모리가 복사 (lazily)되기 때문에 부모와 자식 모두 프로세스를 중지하고 중지를 기다립니다. 그러나 예외가 언급되었으므로 상위 프로세스 만이이를 수행 할 수 있습니다. os.fork을 사용하는 대신 multiprocessing.Process을 사용하면 Manager을 닫으려고하지 않는 새 프로세스가 생성됩니다. sys.exit.