gpt4 book ai didi

python - 在系统调用期间捕获/阻塞 SIGINT

转载 作者:太空狗 更新时间:2023-10-29 20:52:57 26 4
gpt4 key购买 nike

我已经编写了一个网络爬虫,我希望能够通过键盘停止它。我不希望程序在我中断时死掉;它需要先将其数据刷新到磁盘。我也不想捕获 KeyboardInterruptedException,因为持久数据可能处于不一致状态。

我目前的解决方案是定义一个信号处理程序来捕获 SIGINT 并设置一个标志;主循环的每次迭代都会在处理下一个 url 之前检查此标志。

但是,我发现如果系统恰好在我发送中断时正在执行 socket.recv(),我会得到这个:

^C
Interrupted; stopping... // indicates my interrupt handler ran
Traceback (most recent call last):
File "crawler_test.py", line 154, in <module>
main()
...
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/socket.py", line 397, in readline
data = recv(1)
socket.error: [Errno 4] Interrupted system call

进程完全退出。为什么会这样?有什么办法可以防止中断影响系统调用?

最佳答案

socket.recv() 在 C 层调用底层的 POSIX 兼容的 recv 函数,后者将返回一个错误代码 EINTR 当进程在 recv() 中等待传入数据时收到 SIGINT。此错误代码可用于 C 端(如果您使用 C 编程)来检测 recv() 返回不是因为套接字上有更多数据可用,而是因为进程收到了 SIGINT。不管怎样,这个错误代码被 Python 变成了一个异常,并且由于它永远不会被捕获,它会终止你的应用程序并显示你看到的回溯。解决方案很简单,就是捕获socket.error,检查错误代码,如果它等于errno.EINTR,则静默忽略异常。像这样:

import errno

try:
# do something
result = conn.recv(bufsize)
except socket.error as (code, msg):
if code != errno.EINTR:
raise

关于python - 在系统调用期间捕获/阻塞 SIGINT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3016369/

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