【问题标题】:Terminate subprocess running in thread on program exit在程序退出时终止在线程中运行的子进程
【发布时间】:2017-04-21 01:50:28
【问题描述】:

基于对这个问题的公认答案: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)),但它实际上在运行子进程的线程退出时执行,而不是在 ma​​in 线程退出时执行。

我也在考虑轮询父pid,但由于proc.wait的情况,我不确定如何实现。

理想的结果是:

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

【问题讨论】:

    标签: python multithreading subprocess


    【解决方案1】:

    使用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'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 2011-06-07
      • 2019-06-03
      • 2013-05-12
      • 2011-06-21
      相关资源
      最近更新 更多