gpt4 book ai didi

c - 收到警报信号时,read() 系统调用不会失败

转载 作者:太空宇宙 更新时间:2023-11-03 23:51:48 24 4
gpt4 key购买 nike

这是我的(部分)服务器端代码

void timeout_handler(int value) {
printf("Handler\n");
return;
}

int main (int argc, char **argv) {
[...]
signal(SIGALRM, timeout_handler);
alarm(seconds);
int result = read(input_socket, buffer, sizeof(buffer));
if (result == -1 && errno == EINTR) {
printf("read() failed\n");
}
[...]
}

其中 input_socket 是与客户端正确连接的 TCP 套接字(如果我从客户端发送数据,服务器会接收它们)。

作为警报信号的测试,我尝试只打开并连接套接字客户端而不发送任何数据。我希望输出像

Handler
read() failed

但结果只是Handler消息,然后进程依然活跃。

为什么 read() 不会因 errno=EINTR 而失败?

最佳答案

同样在 OSX 上,某些系统调用在被信号中断时默认重新启动

siginterrupt() 可用于更改此行为。下面一行(在 alarm() 被调用之前的某处)应该让程序按照 OP 的预期运行:

siginterrupt(SIGALRM, 1);

来自 OSX 文档(由我强调):

For some system calls, if a signal is caught while the call is executing and the call is prematurely terminated, the call is automatically restarted. Any handler installed with signal(3) will have the SA_RESTART flag set, meaning that any restartable system call will not return on receipt of a signal. The affected system calls include read(2), write(2), sendto(2), recvfrom(2), sendmsg(2), and recvmsg(2) on a communications channel or a low speed device and during a ioctl(2) or wait(2). However, calls that have already committed are not restarted, but instead return a partial success (for example, a short read count). These semantics could be changed with siginterrupt(3).

这在 Linux 上是不同的,例如,在 Linux 上重新启动可能被中断的系统调用需要通过发送的信号明确请求。

关于c - 收到警报信号时,read() 系统调用不会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18548849/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com