无法将sigaction与计时器信号一起使用

无法将sigaction与计时器信号一起使用,c,C,大家好 但是,我尝试使用sigaction()却没有成功 这是我的代码: int main() { struct sigaction act, oact; act.sa_handler = (void *)g; sigaction(SIGVTALRM,&act,&oact); struct itimerval tv; tv.it_value.tv_sec = 2; //time of first timer tv.it_value.tv_usec = 0; //time o

大家好 但是,我尝试使用sigaction()却没有成功 这是我的代码:

int main()
{

struct sigaction act, oact;
act.sa_handler = (void *)g;

sigaction(SIGVTALRM,&act,&oact);

struct itimerval tv;
tv.it_value.tv_sec = 2; //time of first timer
tv.it_value.tv_usec = 0; //time of first timer
tv.it_interval.tv_sec = 2; //time of all timers but the first one
tv.it_interval.tv_usec = 0; //time of all timers but the first one

setitimer(ITIMER_VIRTUAL, &tv, NULL);

for (;;);
}
这是g()

当我运行代码时,我陷入了第一个for(;;)循环,而没有到达g()。 如果我将g()定义为处理信号的函数,为什么不使用它呢


谢谢

首先,您应该确保输入的
struct sigaction
结构是干净的:

sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_handler = g;
然后,您应该挂起该进程,而不是使用for循环“spin wait”:

最后,应该正确定义信号处理程序,不要使用printf()函数,因为在存在信号的情况下,printf()函数是不安全的,不应该在信号处理程序中使用。相反,它应该设置一个原子标志:

static volatile sig_atomic_t g_called;

void g(int sig) {
    g_called = 1;
}

基本问题是您使用的是未初始化的
sigaction
结构。使用以下命令初始化它:

struct sigaction act = {0};

或者在调用
sigaction
之前使用
memset
将其清除

sigaction
setitimer
的调用是否返回0(表示无错误)?看起来这些函数的用法是正确的……从信号处理程序调用
printf
(或其他非异步信号安全函数)是有效和安全的,只要非异步信号安全函数没有被信号处理程序中断。例如,如果信号出现时运行的唯一代码是(;;)的
然后您可以使用信号处理程序中想要的任何函数。
sigsuspend()
通常是有意义的,但在这种情况下它将永远等待,因为只有在进程以用户模式执行时,
ITIMER\u VIRTUAL
计时器才会运行。另外还有两个问题,stdout可能是行缓冲的,所以printf不会显示-其次,你不应该在信号处理程序中调用printf,因为printf不是异步信号安全的(尽管对于这样的小测试用例可能是无害的),正如我对Steve的回答所评论的,调用
printf
在信号处理程序中是完全安全的,只要在调用信号处理程序时不能执行其他非异步信号安全的函数。POSIX在XSH第2.4.3节末尾详细说明了这一点。All-zero不是
sigset_t
的可移植初始化<必须使用code>sigeptypyset()或
sigfillset()
。公平地说,您仍然需要初始化
sigset\u t
。但至少旗帜等不会是随机的。
static volatile sig_atomic_t g_called;

void g(int sig) {
    g_called = 1;
}
struct sigaction act = {0};