簡體   English   中英

使用 sigwait 阻塞特定信號而不阻塞 SIGINT

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM