【发布时间】:2011-04-09 10:28:53
【问题描述】:
我找到了select() 的服务器,我想从一些客户端接收它。
但我发现服务器会被 gdb 在read() 中阻止。
所以我想通过添加SIGALRM 来解决它,但是
当发生超时时,它仍然在read() 中被阻止。
发生这种情况是因为系统调用会自动重新启动,read()
SIGALRM 信号处理程序返回时不会中断。
这个解释正确吗?
【问题讨论】:
标签: c linux networking
我找到了select() 的服务器,我想从一些客户端接收它。
但我发现服务器会被 gdb 在read() 中阻止。
所以我想通过添加SIGALRM 来解决它,但是
当发生超时时,它仍然在read() 中被阻止。
发生这种情况是因为系统调用会自动重新启动,read()
SIGALRM 信号处理程序返回时不会中断。
这个解释正确吗?
【问题讨论】:
标签: c linux networking
解决这个问题的通常方法是使用SOCK_NONBLOCK to socket(2) 或O_NONBLOCK to fcntl(2) 的F_SETFL 命令。一旦套接字被标记为非阻塞,当您尝试从中读取时它永远不会阻塞,并且您无需尝试跨越阻塞或非阻塞之间的鸿沟。你确定select(2) 设置文件描述符吗? select(2) 联机帮助页确实描述了您看到所见内容的一个原因,但似乎不太可能:
在 Linux 下,
select()可能会将套接字文件描述符报告为 “准备阅读”,尽管随后的阅读 块。例如,这可能在数据到达时发生 但经检查有错误的校验和并被丢弃。 可能存在文件描述符在其他情况下 虚假地报告为准备就绪。因此使用起来可能更安全O_NONBLOCK在不应阻塞的套接字上。
如果您真的只是想阻止自动重启,请查看sigaction(2) 中的SA_RESTART 以防止可重启的系统调用重启。
【讨论】: