对于socket接口(指connect/send/recv/accept..等等后面不重复,不包括不能设置非阻塞的如select),在阻塞模式下有可能因为发生信号,返回EINTR错误,由用户做重试或终止。
但是,在非阻塞模式下,是否出现这种错误呢?
对此,重温了系统调用、信号、socket相关知识,得出结论是:[b]不会出现[/b]。
首先,
1.信号的处理是在用户态下进行的,也就是必须等待一个系统调用执行完了才会执行进程的信号函数,所以就有了信号队列保存未执行的信号
2.用户态下被信号中断时,内核会记录中断地址,信号处理完后,如果进程没有退出则重回这个地址继续执行
socket接口是一个系统调用,也就是即使发生了信号也不会中断,必须等socket接口返回了,进程才能处理信号。
也就是,EINTR错误是socket接口主动抛出来的,不是内核抛的。socket接口也可以选择不返回,自己内部重试之类的..
那阻塞的时候socket接口是怎么处理发生信号的?
举例
socket接口,例如recv接口会做2件事情,
1.检查buffer是否有数据,有则复制清除返回
2.没有数据,则进入睡眠模式,当超时、数据到达、发生错误则唤醒进程处理
socket接口的实现都差不了太多,抽象说
1.资源是否立即可用,有则返回
2.没有,就等...
对于
1.这个时候不管有没信号,也不返回EINTR,只管执行自己的就可以了
2.采用睡眠来等待,发生信号的时候进程会被唤醒,socket接口唤醒后检查有无未处理的信号(signal_pending)会返回EINTR错误。
所以
socket接口并不是被信号中断,只是调用了睡眠,发生信号睡眠会被唤醒通知进程,然后socket接口选择主动退出,这样做可以避免一直阻塞在那里,有退出的机会。非阻塞时不会调用睡眠。
我们看看linux内核里的实现
linux kernel 3.5.5
[img]http://dl.iteye.com/upload/attachment/0074/6421/fabf67c1-3cd6-387a-a1d9-0b92b6335e02.png[/img]
[img]http://dl.iteye.com/upload/attachment/0074/6429/84f2c766-80b7-33b8-bf4c-6999f0ebc575.png[/img]
[img]http://dl.iteye.com/upload/attachment/0074/6583/172ea1e3-a97d-3676-8468-6bde783d9f81.png[/img]
参考资料:
《UNIX环境高级编程》
《UNIX网络编程》
《TCP/IP详解 卷2:实现》
《深入Linux内核架构》
但是,在非阻塞模式下,是否出现这种错误呢?
对此,重温了系统调用、信号、socket相关知识,得出结论是:[b]不会出现[/b]。
首先,
1.信号的处理是在用户态下进行的,也就是必须等待一个系统调用执行完了才会执行进程的信号函数,所以就有了信号队列保存未执行的信号
2.用户态下被信号中断时,内核会记录中断地址,信号处理完后,如果进程没有退出则重回这个地址继续执行
socket接口是一个系统调用,也就是即使发生了信号也不会中断,必须等socket接口返回了,进程才能处理信号。
也就是,EINTR错误是socket接口主动抛出来的,不是内核抛的。socket接口也可以选择不返回,自己内部重试之类的..
那阻塞的时候socket接口是怎么处理发生信号的?
举例
socket接口,例如recv接口会做2件事情,
1.检查buffer是否有数据,有则复制清除返回
2.没有数据,则进入睡眠模式,当超时、数据到达、发生错误则唤醒进程处理
socket接口的实现都差不了太多,抽象说
1.资源是否立即可用,有则返回
2.没有,就等...
对于
1.这个时候不管有没信号,也不返回EINTR,只管执行自己的就可以了
2.采用睡眠来等待,发生信号的时候进程会被唤醒,socket接口唤醒后检查有无未处理的信号(signal_pending)会返回EINTR错误。
所以
socket接口并不是被信号中断,只是调用了睡眠,发生信号睡眠会被唤醒通知进程,然后socket接口选择主动退出,这样做可以避免一直阻塞在那里,有退出的机会。非阻塞时不会调用睡眠。
我们看看linux内核里的实现
linux kernel 3.5.5
[img]http://dl.iteye.com/upload/attachment/0074/6421/fabf67c1-3cd6-387a-a1d9-0b92b6335e02.png[/img]
[img]http://dl.iteye.com/upload/attachment/0074/6429/84f2c766-80b7-33b8-bf4c-6999f0ebc575.png[/img]
[img]http://dl.iteye.com/upload/attachment/0074/6583/172ea1e3-a97d-3676-8468-6bde783d9f81.png[/img]
参考资料:
《UNIX环境高级编程》
《UNIX网络编程》
《TCP/IP详解 卷2:实现》
《深入Linux内核架构》