2016-12-06 1 views
1

이 질문에 대한 대답은 다음과 같습니다. python-subprocess-callback-when-cmd-exits 별도의 스레드에서 하위 프로세스를 실행 중이며 하위 프로세스 완료 후 호출 가능 프로그램이 실행됩니다. 다행이지만 문제는 스레드가 데몬으로 실행 되더라도 프로그램이 정상적으로 종료 된 후에도 서브 프로세스가 계속 실행되거나 kill -9, Ctrl + C 등으로 죽임을당하는 것입니다.프로그램 종료시 스레드에서 실행중인 하위 프로세스 종료

다음은 아주 간단한 예 (2.7에서 실행) :

import threading 
import subprocess 
import time 
import sys 


def on_exit(pid): 
    print 'Process with pid %s ended' % pid 

def popen_with_callback(cmd): 

    def run_in_thread(command): 
     proc = subprocess.Popen(
      command, 
      shell=False 
     ) 
     proc.wait() 
     on_exit(proc.pid) 
     return 

    thread = threading.Thread(target=run_in_thread, args=([cmd])) 
    thread.daemon = True 
    thread.start() 
    return thread 

if __name__ == '__main__': 
    popen_with_callback(
     [ 
      "bash", 
      "-c", 
      "for ((i=0;i<%s;i=i+1)); do echo $i; sleep 1; done" % sys.argv[1] 
     ]) 
    time.sleep(5) 
    print 'program ended' 

메인 스레드가 더 이상 서브 프로세스의 모든 이상 지속되면 괜찮 :

(venv)~/Desktop|➤➤ python testing_threads.py 3 
> 0 
> 1 
> 2 
> Process with pid 26303 ended 
> program ended 

메인 스레드가 하위 프로세스보다 지속하는 경우는, 서브 프로세스가 계속 결국 멈출 때까지 실행 :

(venv)~/Desktop|➤➤ python testing_threads.py 8 
> 0 
> 1 
> 2 
> 3 
> 4 
> program ended 
(venv)~/Desktop|➤➤ 5 
> 6 
> 7 
# hanging from now on 

주 프로그램이 완료되었거나 종료 된 경우 하위 프로세스를 종료하는 방법은 무엇입니까? 나는 atexit.register(os.kill(proc.pid, signal.SIGTERM))proc.wait 직전에 사용하려했으나 메인 스레드가 종료 될 때가 아니라 서브 프로세스를 실행하는 스레드가 종료 될 때 실제로 실행됩니다.

나는 또한 부모 PID에 대한 폴링을 고려하고 있었지만, proc.wait 상황 때문에 구현 방법을 잘 모르겠습니다.

이상적인 결과는 다음과 같습니다

(venv)~/Desktop|➤➤ python testing_threads.py 8 
> 0 
> 1 
> 2 
> 3 
> 4 
> program ended 
> Process with pid 1234 ended 

답변

0

사용 Thread.join 방법, 블록 주 스레드이 스레드가 종료 될 때까지 :

if __name__ == '__main__': 
    popen_with_callback(
     [ 
      "bash", 
      "-c", 
      "for ((i=0;i<%s;i=i+1)); do echo $i; sleep 1; done" % sys.argv[1] 
     ]).join() 
    print 'program ended' 
관련 문제