我通过 select()
找到了一个服务器,我想从一些客户端接收它。
但是我发现服务器会在 read()
中被 gdb 阻塞。
所以我想通过添加一个SIGALRM
来解决它,但是
当发生超时时,它仍然阻塞在 read()
中。
发生这种情况是因为,系统调用会自动重新启动,read()
当 SIGALRM 信号处理程序返回时不会中断。
这个解释正确吗?
最佳答案
通常解决这个问题的方法是使用 SOCK_NONBLOCK
到 socket(2)
或 O_NONBLOCK
到 fcntl(2)
的 F_SETFL
命令。一旦套接字被标记为非阻塞,当您尝试从中读取时它永远不会阻塞,并且您不需要尝试跨越阻塞或非阻塞之间的鸿沟。您确定 select(2)
设置了文件描述符吗? select(2)
联机帮助页确实描述了您看到所见内容的原因之一,但似乎不太可能:
Under Linux,
select()
may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination has wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to useO_NONBLOCK
on sockets that should not block.
如果您真的只想阻止自动重启,请查看 sigaction(2)
中的 SA_RESTART
以防止可重启的系统调用重启。
关于c - 可重入函数 read(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5604467/