[英]Use sigwait to block a specific signal without blocking SIGINT
我有一個運行循環的程序,每次在循環結束時,進程應該休眠幾秒鍾(秒數不是恆定的,在每個循環中計算)或者直到進程收到SIGINT
,我使用了alarm()
和sigwait()
來執行此操作,但它阻止了我不想要的ctrl+c
信號(即SIGINT
),我希望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 signals\n");
sigemptyset(&sigs);
sigaddset(&sigs, SIGALRM);
sigprocmask(SIG_BLOCK, &sigs, NULL);
}
void wait_for_alarm(int interval)
{
printf("setting up alarm for %d seconds\n", interval);
alarm(interval);
printf("waiting for signal\n");
int sig_num = sigwait(&sigs, NULL);
// sigwaitinfo()
if (sig_num == 0)
{
printf("I received the alarm signal, breaking the wait\n");
}
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
並且應該正常處理所有其他信號(即 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 signals\n");
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 seconds\n", interval);
alarm(interval);
printf("waiting for signal\n");
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 wait\n");
}
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;
}
代碼現在按我的預期工作,我不確定這是否是最好的解決方案,因為我只處理兩個信號並且不知道其余信號是如何處理的(也許其中一些信號很重要以初始化系統為例)。 如果有人有更好的解決方案,我會暫時不接受我的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.