python - 线程时如何中断 Python I/O 操作?

标签 python multithreading io signals sigint

例如,

with open("foo") as f:
  f.read()
(但它可能是文件写入、DNS 查找、任何数量的其他 I/O 操作。)
如果我在读取 (SIGINT) 时中断该程序,则 I/O 操作将停止并且 KeyboardInterrupt被抛出,终结器运行。
但是,如果这发生在主线程以外的线程上,则不会中断 I/O 操作。
所以... 如何中断另一个线程上的 I/O 操作 (类似于它在主线程上的中断方式)?

最佳答案

键盘中断事件总是在主线程上捕获,它们不会直接影响其他线程(在某种意义上它们不会因为 Ctrl+C 而被中断)。 src1 src2 (in a comment)
在这里,您有一个长 IO 绑定(bind)操作的示例示例,这让我们有时间在它完成之前将其杀死。 KeyboardInterrupt 可以正常工作。

import random
import threading


def long_io(file_name):
    with open(file_name, "w") as f:
        i = 0
        while i < 999999999999999999999999999:
            f.write(str(random.randint(0, 99999999999999999999999999)))
            i += 1


t = threading.Thread(target=long_io, args=("foo",), daemon=True)
t.start()

# keep the main thread alive, listening to possible KeyboardInterupts
while t.is_alive():
    t.join(1)  # try to join for 1 second, this gives a small window between joins in which the KeyboardInterrupt can rise
请注意:
  • 该线程被标记为 daemon ;这样,在 KeyboardInterrupt 上,主线程不会等到 IO 完成,而是将其杀死。您可以按照 here 的说明使用非守护线程(推荐) ,但是对于这个例子来说,直接杀死它们就足够了。

  • A thread can be flagged as a “daemon thread”. The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set through the daemon property or the daemon constructor argument. Daemon threads are abruptly stopped at shutdown. Their resources (such as open files, database transactions, etc.) may not be released properly. If you want your threads to stop gracefully, make them non-daemonic and use a suitable signalling mechanism such as an Event. src


    make the child thread daemonic, which means that its parent (the main thread here) will kill it when it exits (only non-daemon threads are not killed but joined when their parent exits) src


  • 我们保持主线程处于事件状态,因此它不会立即完成,而是等待子线程完成。否则,主线程(负责检测键盘中断的线程)将消失(如果子线程是守护线程则杀死它,或者如果它不是守护线程则等待连接)。我们可以使用简单的 t.join()为此,但我们没有。为什么?因为KeyboardInterrupt也会受到影响,并且只有在连接完成后才会引发。

  • the execution in the main thread remains blocked at the line thread.join(). src

    关于python - 线程时如何中断 Python I/O 操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66696797/

    相关文章:

    python - Tornado 的 ORM

    c - 在 Linux 中从 Bio 结构散列数据

    linux - 不关闭 pty 表示不再输入

    python - django中有没有什么方法可以在不创建models.py文件的情况下使用数据库?

    python - 任何快速的 Python GUI 来显示来自相机的实时图像

    multithreading - 如何保持线程的消息泵 react 性

    Java:如何创建一个 Stop JButton 来停止 Runnable() 线程?

    c# - 有没有办法暂停所有 Threading.Timer 计时器?

    java - 为什么我的宇宙飞船没有出现?

    python - 如何帮助 Pylance 了解动态添加的类属性