【发布时间】:2019-07-31 20:24:10
【问题描述】:
我正在尝试编写一个程序,该程序涉及向进程发送信号以通知它暂停一段时间并在收到另一个信号后重新开始工作。我写了一个这样的信号处理程序:
void sig_handler(int alrm)
{
if(sig_rcv==0)
{
printf("Signal received..sig_rcv value: %d\n",sig_rcv);
sig_rcv = (sig_rcv+1)%2;
printf("After increment sig_rcv value: %d\n",sig_rcv);
signal(SIGUSR1,sig_handler);
if(pause()<0)
{
printf("Signal received again..\n");
}
}
else
{
sig_rcv = (sig_rcv+1)%2;
printf("Signal received..sig_rcv value: %d\n",sig_rcv);
signal(SIGUSR1,sig_handler);
}
printf("Exiting..\n");
}
这里我维护一个全局变量 sig_rcv,它最初为 0,如果在它为零时接收到信号,它将进入 if 条件并暂停另一个信号。另一方面,如果它在收到信号时sig_rcv 是 1,它只会改变那个变量的值。 我以这种方式编写信号处理程序的目的是将相同的信号用于两个不同的目的。我使用了这个系统调用:
signal(SIGUSR1,sig_handler);
现在,当我将 SIGUSR1 发送到它正在执行的进程时,直到 pause()statement。但是在第二次发送 SIGUSR1 后,它没有任何效果。它只是在暂停语句处冻结。在我使用另一个信号来移除暂停状态后,这个问题得到了解决,例如:
void sig_handler2(int a)
{
sig_rcv = (sig_rcv+1)%2;
printf("Restarting reading...\n");
}
和
signal(SIGUSR2,sig_handler2);
在这种情况下效果很好。 所以,我的问题是,为什么会发生这种现象?我们不能在执行为同一信号编写的信号处理程序时等待一个信号吗?如果是这样,原因是什么?有没有什么方法可以在不使用 SIGUSR2 的情况下达到同样的效果?
【问题讨论】:
-
这只是一个小细节,但仍然:虽然
sig_rcv = (sig_rcv+1)%2确实完成了工作,但同样可以通过sig_rcv = 1-sig_rcv甚至sig_rcv ^= 1更优雅地实现。关于实际问题,通常的做法是让程序的“主循环”看起来像while (running) ...(其中running是一个全局变量),并让信号处理程序简单地更改running。这样您就可以在单个信号处理程序中检查running的值,而不是对两个不同的信号使用两个不同的处理程序。 -
您使用的是什么操作系统?
-
@MarkPlotnick Ubuntu 18.04