gpt4 book ai didi

python - 使用 ^C/KeyboardInterrupt 在子线程中中断 Python raw_input()

转载 作者:太空狗 更新时间:2023-10-29 21:01:39 25 4
gpt4 key购买 nike

在多线程 Python 程序中,一个线程有时会使用内置的 raw_input() 请求控制台输入.我希望能够在 raw_input 提示符下通过在 shell 中键入 ^C 来关闭程序(即,使用 SIGINT 信号)。但是,当子线程正在执行 raw_input 时,键入 ^C 不会执行任何操作——直到我按下返回(离开 raw_input)才会引发 KeyboardInterrupt。

例如,在下面的程序中:

import threading

class T(threading.Thread):
def run(self):
x = raw_input()
print x

if __name__ == '__main__':
t = T()
t.start()
t.join()

在输入完成之前,键入 ^C 什么都不做。但是,如果我们只调用 T().run()(即单线程情况:只在主线程中运行 raw_input),^C 会立即关闭程序。

据推测,这是因为 SIGINT 被发送到主线程,主线程被挂起(等待 GIL),而 fork 线程在控制台读取时阻塞。主线程在 raw_input 返回后获取 GIL 之前不会执行其信号处理程序。 (如果我对此有误,请纠正我——我不是 Python 线程实现方面的专家。)

有没有办法以类似于 raw_input 的方式从 stdin 读取,同时允许 SIGINT 由主线程处理,从而降低整个进程?

[我在 Mac OS X 和一些不同的 Linux 上观察到上述行为。]


编辑:我错误地描述了上面的潜在问题。在进一步调查中,是主线程对 join() 的调用阻止了信号处理:Guido van Rossum 自己解释说 the underlying lock acquire in join is uninterruptible .这意味着信号实际上被推迟到整个线程完成 - 所以这实际上与 raw_input 完全无关(只是后台线程阻塞的事实,因此连接不会完成)。

最佳答案

当 join 在没有超时的情况下被调用时,它是不可中断的,但是当它被超时调用时,它是可中断的。尝试添加任意超时并将其置于 while 循环中:

while my_thread.isAlive():
my_thread.join(5.0)

关于python - 使用 ^C/KeyboardInterrupt 在子线程中中断 Python raw_input(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9269338/

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