2016-12-06 104 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 

如何在主程序完成或終止時終止子進程?我試圖在proc.wait之前使用atexit.register(os.kill(proc.pid, signal.SIGTERM)),但是當運行子進程的線程退出時它實際上執行,而不是在線程退出時執行。

我也在考慮爲父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' 
相關問題