如何立即停止正在运行单元测试的 python 子进程?终止并杀死不起作用

发布于 2024-09-11 07:47:36 字数 621 浏览 12 评论 0原文

我有一个 Tkinter GUI 运行两个线程,GUI 的主要线程和工作线程。工作线程使用以下代码创建一个子进程:

myProcess = subprocess.Popen(['python', '-u', 'runTests.py'],  
                         stdout=subprocess.PIPE, 
                         stderr=subprocess.STDOUT)

文件 runTests.py 进行一些设置,然后使用以下命令运行单元测试文件:

execfile('myUnitTests.py')

文件 myUnitTests.py 有几个单元测试,其中一些需要五分钟以上的时间才能运行。 在 GUI 中,我单击一个按钮来停止运行测试。这反过来又使工作线程发送信号来停止子进程:

myProcess.terminate()

终止命令不会立即停止进程,而是等到当前单元测试运行完毕然后终止进程? 我尝试过使用 os.kill,但得到与 Terminate() 相同的结果。

知道如何使我的程序更具响应性,以便它立即终止子进程吗?

I have a Tkinter GUI running two threads, the main tread for the GUI and a worker thread. The worker thread creates a subprocess using the following code:

myProcess = subprocess.Popen(['python', '-u', 'runTests.py'],  
                         stdout=subprocess.PIPE, 
                         stderr=subprocess.STDOUT)

The file runTests.py does some setup and then runs a unit test file using the following command:

execfile('myUnitTests.py')

The file myUnitTests.py has several unit tests some that take over five minutes to run.
From the GUI I click a button to stop running the tests. This in turn makes the worker thread send a signal to stop the subprocess:

myProcess.terminate()

The terminate command does not stop the process right away, it waits until the current unit test finishes running and then it terminates the process?
I have tried to use os.kill but I get the same results as with terminate().

Any idea of how can I make my program more responsive so that it kill the subprocess right away?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

朱染 2024-09-18 07:47:36

Python 文档 [ http://docs.python.org/library/signal.html ] 说:

  • 尽管就 Python 用户而言,Python 信号处理程序是异步调用的,但它们只能发生在 Python 解释器的“原子”指令之间。这意味着在纯粹用 C 实现的长计算期间到达的信号(例如对大量文本进行正则表达式匹配)可能会延迟任意时间。

因此,如果您的五分钟单元测试正在执行“纯粹用 C 实现的长计算”,并且您的单元测试工具安装了 SIGTERM 的处理程序,那么这就是您的问题。如果是这样,请尝试使用 myProcess.kill 而不是 myProcess.terminate (或者,如果您还没有 2.6,则使用 myProcess.send_signal(9) )。 SIGKILL 无法从用户空间捕获,并且应该立即生效。

警告:任何应该在单元测试框架之外运行的清理操作都不会被执行。

The Python documentation [ http://docs.python.org/library/signal.html ] says:

  • Although Python signal handlers are called asynchronously as far as the Python user is concerned, they can only occur between the “atomic” instructions of the Python interpreter. This means that signals arriving during long calculations implemented purely in C (such as regular expression matches on large bodies of text) may be delayed for an arbitrary amount of time.

So if your five-minute unit test is doing "a long calculation implemented purely in C", and your unit test harness installs a handler for SIGTERM, that's your problem. If so, try myProcess.kill instead of myProcess.terminate (or, if you haven't got 2.6, myProcess.send_signal(9)). SIGKILL is uncatchable from user space and should have immediate effect.

Warning: any clean-up actions that are supposed to run on the way out of your unit test framework will not be executed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文