使用SIGWAIT阻止特定信号而不阻止SIGINT

发布于 2025-02-11 15:26:18 字数 1815 浏览 2 评论 0原文

我有一个程序可以运行一个循环的程序,每次在循环的末尾,该过程应睡几秒钟(秒数不是恒定的,并且在每个循环中计算)或直到该过程接收到sigint < /code>,我使用armard()sigwait()来执行此操作,但它阻止了ctrl+ctrl+c signal(即>)我不想要的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)该程序不会中断它不断等待,直到$ armard_wait已经过去或直到我发送sigalrm,我想做的是只有逻辑句柄sigalrm,并且应正常处理其他所有信号(即即使程序在等待sigalrm 信号)

I have a program that runs a loop, each time at the end of the loop, the process should sleep for some seconds(the number of seconds is not constant and is calculated at each loop) or until the process receives SIGINT, I used alarm() and sigwait() to do this but it's blocking the ctrl+c signal(i.e SIGINT) which I don't want, I want SIGINT to be received and acted upon normally, sample code below (note that somefunction() below is just an example, in the original code it does real calculation instead of using 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;
}

The results I'm getting is that when the execution reaches sigwait and I send the SIGINT signal(through ctrl-c) the program is not interrupted instead it keeps waiting until $alarm_wait has elapsed or until I send SIGALRM, what I want to do is have the logic only handles SIGALRM and every other signal should be handled normally(i.e SIGINT should interrupt the program even while it's waiting for SIGALRM signal)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦太阳 2025-02-18 15:26:18

感谢@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;
}

现在,代码现在可以正常工作,我不确定这是否是最好的解决方案,因为我是我'M仅处理两个信号,并且不知道其余信号如何处理(例如,其中一些信号对于初始化系统很重要)。
我将在某个时候不接受我的答案,因为某人有更好的解决方案。

Thanks to @Shawn for pointing out the second argument of sigwait I was able to solve my issue by also blocking SIGINT and using the second argument of sigwait to determine if the signal is SIGINT then execute 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;
}

The code now works as i would expect, i'm not sure if this is the best solution since i'm only handling two signals and don't know how the rest of the signals are being handled(maybe some of these signals are important for the init system for example).
I will leave my answer unaccepted for sometime incase someone has a better solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文