杀死在线程内运行的子进程

时间:2017-07-30 15:43:10

标签: python python-3.x pyqt

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

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

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

使用线程的终止方法杀死线程没有问题。 但是,这并没有终止子流程。

我尝试过使用Popen而不是运行但是我不能让它像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()

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

1 个答案:

答案 0 :(得分:1)

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

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

    示例代码是......如下:

    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。