子进程在独立线程中运行

1 投票
1 回答
525 浏览
提问于 2025-04-17 03:15

我在想下面这个类是否合理。我用它来为我的测试环境中的每个测试启动一堆模拟器。

    class SubProcessInOwnThread(threading.Thread):
        def __init__(self, arguments, currentWorkingDirectory):
            self.arguments = arguments
            self.currentWorkingDirectory = currentWorkingDirectory
            threading.Thread.__init__(self)
            self.isTerminated = False

        def run(self):
            try:
                self.subProcess = subprocess.Popen(self.arguments, cwd=self.currentWorkingDirectory)
                self.subProcess.wait()
            finally:
                self.isTerminated = True

        def kill(self):
            while not self.isTerminated:
                try:
                    self.subProcess.kill()
                except:
                    time.sleep(0.1)

一些场景:

    # Normal
    subProcessThreadArguments = ["cmd.exe"]
    subProcessThread = SubProcessInOwnThread(subProcessThreadArguments,r"C:\\")
    subProcessThread.start()
    time.sleep(5)
    subProcessThread.kill()

    # Process killed very quickly
    subProcessThreadArguments = ["cmd.exe"]
    subProcessThread = SubProcessInOwnThread(subProcessThreadArguments,r"C:\\")
    subProcessThread.start()
    subProcessThread.kill()

    # Incorrect configuration
    subProcessThreadArguments = ["cmdsfgfg.exe"]
    subProcessThread = SubProcessInOwnThread(subProcessThreadArguments,r"C:\\")
    subProcessThread.start()
    time.sleep(5)
    subProcessThread.kill()

所以我可以这样创建模拟器:

    subProcessThreadArguments1 = ["sim1.exe"]
    subProcessThread1 = SubProcessInOwnThread(subProcessThreadArguments1,r"C:\\")
    subProcessThread1.start()

    subProcessThreadArguments2 = ["sim2.exe"]
    subProcessThread2 = SubProcessInOwnThread(subProcessThreadArguments2,r"C:\\")
    subProcessThread2.start()

    # do test...

    subProcessThread1.kill()
    subProcessThread2.kill()

我很想知道有什么改进的建议。我应该考虑使用with关键字吗?如果考虑的话,它有什么好处呢?

谢谢!

1 个回答

2

我不明白为什么要在这里让一个单独的线程卡在 wait() 里。直接处理子进程就可以像这样工作:

class SubProcessWithoutThread(object):
    def __init__(self, arguments, currentWorkingDirectory):
        self.arguments = arguments
        self.currentWorkingDirectory = currentWorkingDirectory
        self.isTerminated = False

    def start(self):
        self.subProcess = subprocess.Popen(self.arguments, cwd=self.currentWorkingDirectory)

    def kill(self):
        while self.subProcess.poll() is None:
            try:
                self.subProcess.kill()
            except:
                time.sleep(0.1)

    __enter__ = start
    def __exit__(self, *x):
        self.kill()

(这个代码没有测试过)

我添加了一些用于上下文管理器的方法,但我觉得这对你没有什么帮助,因为你需要创建很多 with 语句,还要处理必要的缩进。

不过,也许我误解了你的意思……

撰写回答