gpt4 book ai didi

python - 为什么我的线程/多处理 python 脚本没有正常退出?

转载 作者:太空狗 更新时间:2023-10-30 02:49:15 24 4
gpt4 key购买 nike

我有一个服务器脚本,我需要能够干净地关闭它。在测试常用的 try..except 语句时,我意识到 Ctrl-C 不能正常工作。通常我会像这样包装长时间运行的任务

try:
...
except KeyboardInterrupt:
#close the script cleanly here

因此任务可以在 Ctrl-C 上干净地关闭。我以前从未遇到过任何问题,但不知何故,当我在这个特定脚本运行时按 Ctrl-C 时,脚本直接退出而没有捕获 Ctrl-C

初始版本是使用 multiprocessing 中的 Process 实现的。我使用 threading 中的 Thread 重写了脚本,但那里存在同样的问题。我以前多次使用过threading,但我对multiprocessing 库还很陌生。无论哪种方式,我以前从未体验过这种 Ctrl-C 行为。

通常我总是实现哨兵等以有序的方式关闭 QueuesThread 实例,但这个脚本只是退出而没有任何响应。

最后,我尝试像这样覆盖 signal.SIGINT

def handler(signal, frame):
print 'Ctrl+C'

signal.signal(signal.SIGINT, handler)
...

这里 Ctrl+C 实际上被捕获了,但是处理程序没有执行,它从不打印任何东西。

除了 threading/multiprocessing 方面,部分脚本还包含 C++ SWIG 对象。我不知道这是否与它有关。我在 OS X Lion 上运行 Python 2.7.2。

那么,有几个问题:

  1. 这是怎么回事?
  2. 我该如何调试它?
  3. 我需要学习什么才能了解​​根本原因?

请注意:脚本的内部结构是专有的,因此我无法提供代码示例。不过,我非常愿意接受指点,这样我就可以自己调试了。我有足够的经验,能够弄清楚是否有人能指出我正确的方向。

编辑:我开始注释掉导入等以查看导致奇怪行为的原因,然后我将范围缩小到导入 C++ SWIG 库。为什么导入 C++ SWIG 库会“窃取”Ctrl-C?然而,我不是 guilty library 的作者,而且我的 SWIG 经验有限,所以真的不知道从哪里开始......

编辑 2: 我刚刚在 Windows 机器上尝试了相同的脚本,在 Windows 7 中,Ctrl-C 按预期被捕获。我真的不会为 OS X 部分操心,脚本无论如何都会在 Windows 环境中运行。

最佳答案

这可能与 Python 管理线程、信号和 C 调用的方式有关。

简而言之 - Ctrl-C 不能中断 C 调用,因为实现需要 python 线程处理信号,而不仅仅是任何线程,而是主线程(经常被阻塞,等待其他线程)。

事实上,长操作可以阻止一切。

考虑一下:

>>> nums = xrange(100000000)
>>> -1 in nums
False (after ~ 6.6 seconds)
>>>

现在,尝试按 Ctrl-C(不间断!)

>>> nums = xrange(100000000)
>>> -1 in nums
^C^C^C (nothing happens, long pause)
...
KeyboardInterrupt
>>>

Ctrl-C 不适用于线程程序的原因是主线程经常被不间断的线程连接或锁阻塞(例如,任何“等待”、“连接”或只是一个空的“主”线程,它在后台导致 python 在任何生成的线程上“加入”)。

尝试插入一个简单的

while True:
time.sleep(1)

在你的主线程中。

如果您有一个长时间运行的 C 函数,请在 C 级进行信号处理(愿原力与您同在!)。

这主要基于 David Beazley 的 video关于这个问题。

关于python - 为什么我的线程/多处理 python 脚本没有正常退出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9139127/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com