可重入函数 read()
我通过 select()
找到了一个服务器,我想从一些客户端接收该服务器。
但我发现服务器会被gdb阻塞在read()
中。
所以我想到通过添加一个SIGALRM
来解决它,但是 当发生超时时,它仍然被阻塞在read()
中。
发生这种情况是因为系统调用会自动重新启动,read()
当 SIGALRM 信号处理程序返回时,不会被中断。
这个解释正确吗?
I have found a server by select()
, which I want to receive from some clients.
But I find that the server will get blocked in read()
by gdb.
So I thought of solving it by adding a SIGALRM
, but
when a timeout occurs, it's still blocked in read()
.
This happens because, system calls are automatically restarted, the read()
is not interrupted when the SIGALRM signal handler returns.
Is this interpretation correct?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
此问题的通常解决方案是使用
SOCK_NONBLOCK
到socket(2)
或O_NONBLOCK
到fcntl(2)
的F_SETFL
命令。一旦套接字被标记为非阻塞,当您尝试从中读取数据时,它就永远不会阻塞,并且您无需尝试跨越阻塞与非阻塞之间的界限。您确定select(2)
设置了文件描述符吗?select(2)
联机帮助页确实描述了您看到所看到内容的原因之一,但似乎不太可能:如果您确实只是想阻止自动重新启动,请查看
sigaction(2)
中的SA_RESTART
以阻止可重新启动的系统调用重新启动。The usual solution to this problem is to use
SOCK_NONBLOCK
tosocket(2)
orO_NONBLOCK
tofcntl(2)
'sF_SETFL
command. Once the socket is marked non-blocking, it'll never block when you try to read from it, and you won't need to try to straddle the divide between blocking or non-blocking. Are you sureselect(2)
set the filedescriptor? Theselect(2)
manpage does describe one reason why you see what you're seeing, but it doesn't seem likely:If you really just want to prevent the automatic restart, look into
SA_RESTART
insigaction(2)
to prevent restartable system calls from restarting.