dan*_*ben 8 python unix signals interrupt system-calls
我写了一个网络爬虫,我希望能够通过键盘停止.当我打断它时,我不希望程序死掉; 它需要先将其数据刷新到磁盘.我也不想抓住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
Run Code Online (Sandbox Code Playgroud)
并且该过程完全退出.为什么会这样?有没有办法阻止中断影响系统调用?
socket.recv()调用recvC层中的基础POSIX兼容函数,EINTR当进程收到一段SIGINT时间等待传入数据时,它将返回错误代码recv().此错误代码可以在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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7371 次 |
| 最近记录: |