Pau*_*per 8 python io multithreading signals sigint
例如,
with open("foo") as f:
f.read()
Run Code Online (Sandbox Code Playgroud)
(但它可能是文件写入、DNS 查找、任意数量的其他 I/O 操作。)
如果我在读取 (SIGINT) 时中断该程序,则 I/O 操作将停止并被KeyboardInterrupt抛出,并且终结器会运行。
但是,如果这发生在主线程以外的线程上,则 I/O 操作不会中断。
那么...如何中断另一个线程上的 I/O 操作(类似于它在主线程上的中断方式)?
键盘中断事件始终在主线程上捕获,它们不会直接影响其他线程(从某种意义上说,它们不会因 a 而被中断Ctrl+C)。src1 src2 (在评论中)
这里有一个长 IO 绑定操作的示例,这让我们有时间在它完成之前终止它。KeyboardInterrupt 按您的预期工作。
\nimport random\nimport threading\n\n\ndef long_io(file_name):\n with open(file_name, "w") as f:\n i = 0\n while i < 999999999999999999999999999:\n f.write(str(random.randint(0, 99999999999999999999999999)))\n i += 1\n\n\nt = threading.Thread(target=long_io, args=("foo",), daemon=True)\nt.start()\n\n# keep the main thread alive, listening to possible KeyboardInterupts\nwhile t.is_alive():\n t.join(1) # try to join for 1 second, this gives a small window between joins in which the KeyboardInterrupt can rise\nRun Code Online (Sandbox Code Playgroud)\n请注意:
\ndaemon;这样,在KeyboardInterrupt上,主线程不会等到IO完成,而是杀死它。您可以按照此处的说明使用非守护线程(推荐),但对于本例来说,直接杀死它们就足够了。\n\n线程可以标记为 \xe2\x80\x9cdaemon 线程\xe2\x80\x9d。该标志的意义在于,当只剩下守护线程时,整个Python程序就会退出。初始值是从创建线程继承的。该标志可以通过 daemon 属性或 daemon 构造函数参数来设置。守护进程线程在关闭时突然停止。它们的资源(例如打开的文件、数据库事务等)可能无法正确释放。如果您希望线程正常停止,请将它们设置为非守护进程并使用合适的信号机制(例如事件)。源代码
\n
\n\n使子线程成为守护线程,这意味着它的父线程(这里是主线程)将在其退出时杀死它(只有非守护线程不会被杀死,而是在其父线程退出时加入)src
\n
t.join()方法来实现这一点,但我们没有。为什么?因为KeyboardInterrupt也会受到影响,并且只有在连接完成后才会被提升。\n\n主线程中的执行仍然阻塞在 thread.join() 行。源代码
\n
| 归档时间: |
|
| 查看次数: |
279 次 |
| 最近记录: |