简体   繁体   English

可重入函数read()

[英]reentrant function read()

I have found a server by select() , which I want to receive from some clients. 我通过select()找到了一个服务器,我想从一些客户端收到它。

But I find that the server will get blocked in read() by gdb. 但我发现服务器将被gdb阻塞在read()

So I thought of solving it by adding a SIGALRM , but when a timeout occurs, it's still blocked in read() . 所以我想通过添加一个SIGALRM来解决它,但是当发生超时时,它仍然在read()被阻塞。

This happens because, system calls are automatically restarted, the read() is not interrupted when the SIGALRM signal handler returns. 发生这种情况是因为,系统调用会自动重新启动,当SIGALRM信号处理程序返回时, read()不会中断。

Is this interpretation correct? 这种解释是否正确?

The usual solution to this problem is to use SOCK_NONBLOCK to socket(2) or O_NONBLOCK to fcntl(2) 's F_SETFL command. 这个问题的通常解决方案是使用SOCK_NONBLOCKsocket(2)O_NONBLOCKfcntl(2)F_SETFL命令。 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 sure select(2) set the filedescriptor? 你确定select(2)设置文件描述符吗? The select(2) manpage does describe one reason why you see what you're seeing, but it doesn't seem likely: select(2)联机帮助页确实描述了您看到所见内容的一个原因,但似乎不太可能:

Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. 在Linux下, select()可以将套接字文件描述符报告为“准备好读取”,而不是后续的读取块。 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 use O_NONBLOCK on sockets that should not block. 因此,在不应阻塞的套接字上使用O_NONBLOCK可能更安全。

If you really just want to prevent the automatic restart, look into SA_RESTART in sigaction(2) to prevent restartable system calls from restarting. 如果您真的只想阻止自动重启,请在sigaction(2)查看SA_RESTART以防止重新启动系统调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM