【问题标题】:Killing sub process that run inside a thread杀死在线程内运行的子进程
【发布时间】:2017-07-30 15:43:09
【问题描述】:

我正在使用 python 3.5.3 和 PyQT 5,并且我已经用它编写了 GUI。 这个 GUI 使用 subprocess.run 运行 python 代码 python 代码。

为了在子进程操作期间让我的 GUI 处于活动状态而不是冻结,我在线程中运行子进程。

在 GUI 我有停止按钮,如果用户按下,我想终止子进程。

使用线程的终止方法来终止线程没有问题。 但这不会终止子进程。

我尝试使用 Popen 代替 run,但我无法让它像 subprocess.run 那样运行。 另外,我更喜欢使用 Python 推荐的方式,这也给了我 check_error 选项

这就是我使用子流程的方式:

class c_run_test_thread(QtCore.QThread):

    def __init__(self,test_file,log_file):
        QtCore.QThread.__init__(self)
        self.test_file = test_file
        self.log_file = log_file

    def __del__(self):
        self.wait()

    def run(self):
        # Thread logic

        try:
            # Run the test with all prints and exceptions go to global log file
            self.test_sub_process = subprocess.run(["python", self.test_file],stdout = self.log_file, stderr = self.log_file,check = True)

    except subprocess.CalledProcessError as error:
        print("Error : {}".format(error))

    # Flush memory to file
    self.log_file.flush(

def stop(self):

    # Flush memory to file
    self.log_file.flush()

我通过

终止线程
# Stop test thread
self.thread_run_test.terminate()

总而言之,我想在杀死子进程的同时杀死线程。

【问题讨论】:

    标签: python python-3.x pyqt


    【解决方案1】:

    可能还有其他更简单的方法,但我所做的是

    1. 使用subprocess.Popen 运行子进程,而不是subprocess.run,因为后者在进程终止之前不会返回
    2. 使用Popen.poll检查进程是否终止
    3. 使用Popen.kill 终止进程

    示例代码将是某事。像下面这样:

    self.test_sub_process = subprocess.Popen(["python", self.test_file],
                                             stdout=self.log_file,
                                             stderr=self.log_file)
    

    等待终止:

    print("Return code: {}".format(self.test_sub_process.wait()))
    

    或者如果你想在等待的时候做点什么:

    while self.test_sub_process.poll() is None:
        doSomething()
    print("Return code: {}".format(self.test_sub_process.poll()))
    

    然后在thread_run_test.terminate(),就可以杀死进程了

    self.test_sub_process.kill()
    

    HTH。

    【讨论】:

    • 您没有将 .run 更改为 Popen 。它有相同的参数吗? .run 方法中的 PIPE 比 os.read 更好,我可以像今天一样使用 Popen 和 PIPE 并且仍然使用 Popen 吗?
    • @Gil.I 已将其更改为使用Popen
    • 当我使用你的建议时,一些标准输出没有写入日志文件。我不知道为什么。相反,我使用了以下内容: self.test_sub_process = subprocess.Popen(["python", self.test_file], stdout = self.log_file, stderr = self.log_file) while (self.test_sub_process.poll() is None): print ("Test is running") print("Return code: {}".format(self.test_sub_process.poll())) 返回代码部分当然是在循环之外,现在日志已满,没有丢失任何数据
    • @Gil.I,有趣的是它可能会丢失一些stdout 消息。 self.test_file 是否同时写入 stderrstdout?我认为应该以不同的方式处理它们。无论如何,看起来你只使用文件对象而不是PIPEs 更方便。我已更新响应以更好地满足您的情况。
    • 我发布了一个后续问题,以了解如何有序地杀死子进程,同时调用所有对象析构函数stackoverflow.com/questions/45422527/…
    猜你喜欢
    • 2018-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多