我通过select()
找到了一个服务器,我想从一些客户端接收它。
但是我发现服务器在read()
中会被gdb阻塞。
所以我想通过添加SIGALRM
来解决它,但是当发生超时时,它仍然在read()
中被阻止。
发生这种情况的原因是,系统调用会自动重新启动,read()
在SIGALRM信号处理程序返回时不会中断。
这种解释正确吗?
此问题的常见解决方案是使用SOCK_NONBLOCK
到socket(2)
或O_NONBLOCK
到fcntl(2)
的F_SETFL
命令。一旦套接字被标记为非阻塞,当你试图从中读取时,它就永远不会阻塞,你也不需要试图跨越阻塞和非阻塞之间的界限。您确定select(2)
设置了文件描述符吗?select(2)
手册页确实描述了你看到你所看到的东西的一个原因,但似乎不太可能:
在Linux下,
select()
可以将套接字文件描述符报告为"准备阅读",尽管如此块。例如,当数据到达时可能会发生这种情况但是在检查时具有错误的校验和并且被丢弃。文件描述符可能存在其他情况谎报已准备好。因此,使用它可能更安全不应阻塞的套接字上的O_NONBLOCK
。
如果您真的只是想阻止自动重新启动,请查看sigaction(2)
中的SA_RESTART
,以阻止可重新启动的系统调用重新启动。