gpt4 book ai didi

c - 为什么在捕获 SIGALRM 后 recvfrom() 仍然阻塞?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:45:17 24 4
gpt4 key购买 nike

我想使用alarm() 来设置recvfrom 的超时时间。但是发现当使用signal()SIGALRM注册一个handler时,一个SIGALRM已经被捕获然后调用了signal handler。但是在从处理程序返回后,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;
}

最佳答案

根据 signal 的手册页,是否重新启动阻塞调用是一个依赖于平台的属性:

The situation on Linux is as follows:

  • The kernel's signal() system call provides System V semantics.
  • By default, in glibc 2 and later, the signal() wrapper function does not invoke the kernel system call. Instead, it calls sigaction(2) using flags that supply BSD semantics. This default behavior is provided as long as a suitable feature test macro is defined: _BSD_SOURCE on glibc 2.19 and earlier or _DEFAULT_SOURCE in glibc 2.19 and later. (By default, these macros are defined; see feature_test_macros(7) for details.) If such a feature test macro is not defined, then signal() provides System V semantics.

因为 BSD 语义等同于使用以下标志调用 sigaction(2):

sa.sa_flags = SA_RESTART;

并且 System V 语义不执行 SA_RESTART,您所看到的是您的程序正在执行 BSD 方式,因此您应该确保使用上述功能测试宏来获取程序的定义行为.

关于c - 为什么在捕获 SIGALRM 后 recvfrom() 仍然阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37894535/

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