捕获SIGALRM后,为什么recvfrom()仍会阻塞?
我想使用捕获SIGALRM后,为什么recvfrom()仍会阻塞?,c,linux,unix,networking,network-programming,C,Linux,Unix,Networking,Network Programming,我想使用alarm()设置recvfrom的超时时间。但是发现当使用signal()为SIGALRM注册处理程序时,SIGALRM已被捕获,然后调用信号处理程序。但是从处理程序返回后,recvfrom()仍然会阻塞,而没有数据到来,也没有EINTR错误。为什么?signal()是否自动设置了SA_RESTART标志? 代码如下: signal(SIGALRM, sig_handler); while(1) { alarm(5); n = recvfrom(sock, buf, B
alarm()
设置recvfrom
的超时时间。但是发现当使用signal()
为SIGALRM
注册处理程序时,SIGALRM
已被捕获,然后调用信号处理程序。但是从处理程序返回后,recvfrom()
仍然会阻塞,而没有数据到来,也没有EINTR
错误。为什么?signal()
是否自动设置了SA_RESTART
标志?
代码如下:
signal(SIGALRM, sig_handler);
while(1)
{
alarm(5);
n = recvfrom(sock, buf, BUF_MAX, 0, (struct sockaddr*)&addr, &len);
if(n < 0)
{
if(errno == EINTR)
{
printf("recvfrom timeout\n");
continue;
}
else
{
printf("recvfrom error\n");
}
}
else
{
printf("data: %s\n", buf);
alarm(0);
}
}
void sig_handler(int signo)
{
return;
}
信号(信号处理器、信号处理器);
而(1)
{
警报(5);
n=recvfrom(sock、buf、buf_MAX、0、(struct sockaddr*)和addr、&len);
if(n<0)
{
如果(errno==EINTR)
{
printf(“recvfrom超时\n”);
继续;
}
其他的
{
printf(“recvfrom错误\n”);
}
}
其他的
{
printf(“数据:%s\n”,buf);
报警(0);
}
}
无效信号处理器(int signo)
{
返回;
}
根据信号的手册页,阻塞呼叫是否重新启动是一个平台相关属性:
Linux上的情况如下:
- 内核的signal()系统调用提供SystemV语义
- 默认情况下,在glibc2及更高版本中,signal()包装函数不调用内核系统调用。相反,它使用提供BSD的标志调用sigaction(2)
语义学。只要定义了合适的功能测试宏,就会提供此默认行为:_BSD_glibc 2.19及更早版本上的源代码或_default_中的源代码
glibc 2.19及更高版本。(默认情况下,已定义这些宏;有关详细信息,请参阅功能测试宏(7))。如果未定义此类功能测试宏,则信号()
提供SystemV语义
因为BSD语义相当于使用以下标志调用sigaction(2)
:
sa.sa_flags = SA_RESTART;
System V semantics不会重新启动,您看到的是您的程序正在以BSD方式运行,因此您应该确保使用上述功能测试宏来定义程序的行为。真正的问题是为什么不使用so_RCVTIMEO?