2017-05-18 8 views
0

최근 파이썬에서 멀티 프로세싱을 사용할 때 좀비 프로세스에 문제가 있습니다.파이썬 어떻게 커널이 종료 될 때 멀티 프로세싱 좀비를 방지하기 위해

나는 여러 프로세스 (작업자)와 다른 프로세스 (프린터)를 만드는 스크립트가 있습니다. 작업자는 msgs를 대기열로 생성하고 프린터는 모든 msg를 대기열에 인쇄해야합니다.

문제는 일반적으로 근로자는 몇 시간 동안 일해야한다는 것입니다. 그러나 때로는 스크립트를 실행 한 후 일부 코드를 변경하고 스크립트를 다시 시작하고 싶습니다. 작업이 끝날 때까지 기다리면 join()을 사용하기 때문에 좀비가 생기지 않습니다. 하지만 Ctrl + C가 내 스파이더에서 작동하지 않기 때문에 커널을 직접 종료하면 모든 프로세스 (좀비)가 계속 작동합니다.

os.ppid을 사용해 보았지만 ppid가 변경되지 않은 것 같습니다. p.daemon = True 시도했지만 둘 다 작동하지 않습니다.

그래서 커널을 종료하면 모든 프로세스가 종료되고 시스템에 좀비가 없는지 확인하는 방법이 있는지 묻고 싶습니다.

덕분에, 예제 코드는 다음과 같습니다 부모가 청소의 가능성없이 갑자기 종료됩니다 때문에

from multiprocessing import Process, Queue 
import time 

def f(num, q): 
    for i in range(100): 
     q.put('f: num=%d\n'% (num,)) 
     time.sleep(10) 
def g(q, filename): 
    while True: 
     with open(filename, 'a') as f: 
      if q.qsize() > 0: 
       item = q.get() 
       if item == None: 
        break 
       else: 
        f.write(item) 
def main(): 
    filename = './log.txt' 
    q = Queue() 
    workers = [Process(target=f, args=(i,q)) for i in range(10)] 
    printer = Process(target=g, args=(q,filename)) 
    for p in workers: 
     p.daemon = True 
     p.start() 
    printer.daemon = True 
    printer.start() 
    for p in workers: 
     p.join() 
    q.put(None) 
    printer.join() 
if __name__ == '__main__': 
    main() 
+1

"커널 종료"란 무엇을 의미합니까? 어떤 명령을 실제로 발급합니까? – noxdafox

+0

실제로 Spyder IDE를 사용하고 Ipython 콘솔의 "현재 명령 중지"또는 삼각형 단추 "파이썬 콘솔의 현재 프로세스 죽이기"를 클릭합니다. 또는 스파이더를 직접 닫습니다. 좀비 프로세스는 항상 존재합니다. 저는 Atom을 사용했고, 스크립트를 실행하고 나중에 Atom을 닫는다면 같은 상황이됩니다. – Yunguan

+0

어떤 OS를 사용하고 있습니까? – noxdafox

답변

0

는 아이들 프로세스가 해제되지 않습니다. 따라서 daemon 플래그는 유용하지 않습니다.

IDE를 사용하는 아이들과 프로세스를 종료하지는 않을 것입니다. 아마 그러한 사용 사례를 고려하지 않았을 것입니다. 오히려 OS 기능에 의존하고 싶습니다.

Windows에서 /T 매개 변수와 함께 Taskkill 명령을 사용할 수 있습니다. taskkill documentation을 참조하십시오.

Linux의 경우 pkill 명령에 -P 매개 변수를 사용할 수 있습니다. Pkill manpage.

마지막 수단은 SIGTERM 신호를 가로 채고 SIGINT로 재 라우팅하는 것입니다. 그러나 나는 이것을 추천하지 않을 것이다.

import os 
from signal import signal, SIGINT, SIGTERM 

def handler(*_): 
    os.kill(os.pid, SIGINT) 

signal.signal(SIGTERM, handler) 

이것은 해킹이며 Windows에서 작동하는지 확신 할 수 없습니다.

+0

고마워. 그래서 유일한 방법은 그 좀비들을 인간적으로 청소하는 것입니다.나는 Taskkill을 시도하고 아주 잘 작동한다. 지금은 SIGTERM의 코드를 이해할 수는 없지만 나중에 약간의 검색을 할 것이다. 다시 한 번 감사드립니다! – Yunguan

+0

답이 유용 할 경우 다른 사람이 쉽게 찾을 수 있도록 답을 표시하십시오. IDE에서 사용자 정의가 가능하면 (Atom 않습니다) 바로 가기를 추가 할 수 있습니다. SIGTERM 대안을 완전히 이해하지 못한다면, 그것을 멀리 두십시오 :). 어쨌든 해킹입니다. – noxdafox

+0

OK! 고마워요 !! :) 지각에 대한 죄송합니다. – Yunguan