C语言 使用sigwait阻塞特定的信号,而不阻塞SIGINT



我有一个运行循环的程序,每次在循环结束时,进程应该睡眠几秒钟(秒数不是恒定的,并且在每个循环中计算),或者直到进程接收SIGINT,我使用alarm()sigwait()来做到这一点,但它阻止了ctrl+c信号(I)。eSIGINT)我不想要,我想要SIGINT被正常接收和操作,下面的示例代码(注意下面的somefunction()只是一个例子,在原始代码中它做真正的计算而不是使用rand())

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/time.h>
#include <unistd.h>
sigset_t sigs;
void setup_alarm()
{
printf("setting up signalsn");
sigemptyset(&sigs);
sigaddset(&sigs, SIGALRM);
sigprocmask(SIG_BLOCK, &sigs, NULL);

}
void wait_for_alarm(int interval)
{
printf("setting up alarm for %d secondsn", interval);
alarm(interval);
printf("waiting for signaln");
int sig_num = sigwait(&sigs, NULL);
// sigwaitinfo()
if (sig_num == 0)
{
printf("I received the alarm signal, breaking the waitn");
}
else if (sig_num == EINVAL)
{
printf("some other error occurred");
perror("signal wait failed unexpectedly");
exit(1);
}
}
int somefunction()
{
srand(time(NULL));
return (rand() % 4) + 1;
}
int main(int argc, char *argv[])
{
int alarm_wait = 0;
setup_alarm();
while (1)
{
// do somework here
alarm_wait = somefunction();
// sleep for $alarm_wait or untill we receive SIGALARM
wait_for_alarm(alarm_wait);
}
return 0;
}

我得到的结果是,当执行达到sigwait并且我发送SIGINT信号(通过ctrl-c)时,程序不会中断,而是一直等待,直到$alarm_wait已经过去或直到我发送SIGALRM,我想要做的是让逻辑只处理SIGALRM,其他信号应该正常处理(I)。e SIGINT应该中断程序,即使它在等待SIGALRM信号)

感谢@Shawn指出sigwait的第二个参数,我能够通过阻止SIGINT并使用sigwait的第二个参数来确定信号是否为SIGINT,然后执行exit(0)来解决我的问题

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/time.h>
#include <unistd.h>
sigset_t sigs;
void setup_alarm()
{
printf("setting up signalsn");
sigemptyset(&sigs);
sigaddset(&sigs, SIGALRM);
sigaddset(&sigs, SIGINT);
sigprocmask(SIG_BLOCK, &sigs, NULL);
}
void wait_for_alarm(int interval)
{
printf("setting up alarm for %d secondsn", interval);
alarm(interval);
printf("waiting for signaln");
int sig;
int sig_num = sigwait(&sigs, &sig);
if(sig == SIGINT)
exit(0);
if (sig_num == 0)
{
printf("I received the alarm signal, breaking the waitn");
}
else if (sig_num == EINVAL)
{
printf("some other error occurred");
perror("signal wait failed unexpectedly");
exit(1);
}
}
int somefunction()
{
srand(time(NULL));
return (rand() % 4) + 1;
}
int main(int argc, char *argv[])
{
int alarm_wait = 0;
setup_alarm();
while (1)
{
// do somework here
alarm_wait = somefunction();
// sleep for $alarm_wait or untill we receive SIGALARM
wait_for_alarm(alarm_wait);
}
return 0;
}

代码现在工作如我所期望的,我不确定这是否是最好的解决方案,因为我只处理两个信号,不知道其余的信号是如何处理的(也许这些信号中的一些是重要的init系统为例)。我暂时不接受我的答案,也许有人有更好的解决办法。

最新更新