다음 코드가 SIGINT 신호를 잠금 해제할 수 없는 이유

다음 코드가 SIGINT 신호를 잠금 해제할 수 없는 이유

나는 Linux Signals를 시도하고 있습니다. 저는 다음과 같은 시나리오를 만들었습니다.

  1. 처음에는 모든 SIGINT신호를 차단합니다 sigprocmask().
  2. 발신자가 SIGUSR1신호를 보내면 SIGINT나머지 프로세스 수명 동안 차단이 해제됩니다.

그러나 첫 번째 단계는 성공적으로 구현되었지만 프로세스 마스크 잠금 해제(또는 변경)가 불가능했습니다 sigprocmask().

내가 뭘 잘못했나요?

#include<stdio.h>
#include<signal.h>
#include<stdlib.h>

sigset_t block_list, unblock_list;

void sigint_handler(int sig)
{
        printf("Ouch!!\n");
}

void sigusr1_handler(int sig)
{
        sigemptyset(&unblock_list);
        sigprocmask(SIG_SETMASK, &unblock_list, NULL);
}


int main(int argc, char **argv)
{
    int count;

    signal(SIGINT, &sigint_handler);
    signal(SIGUSR1, &sigusr1_handler);

    sigemptyset(&block_list);
    sigaddset(&block_list, SIGINT);
    sigprocmask(SIG_SETMASK, &block_list, NULL);

    for(count=1; ;++count)
    {
            printf("Process id: %ld\t%d\n", (long)getpid(), count);
            sleep(4);
    }

    exit(EXIT_SUCCESS);
    }

$kill -n SIGINT <pid>

$kill -n SIGUSER1 <pid> //This call should unblock sigint_handler() for rest of the process life, but it is only unblocking for one time. Everytime I have call $kill -n SIGUSER1 <pid> to unblock SIGINT.

참고: 단순화를 위해 오류 처리가 제거되었습니다.

답변1

신호 처리기에서 반환된 후 커널은 신호 마스크를 복원합니다. 이는 다음으로 인해 발생합니다.기준:

설치된 신호 잡기 함수 내에서 스레드의 신호 마스크가 변경되면 sigaction()신호 잡기 함수에서 돌아올 때 신호 마스크를 복원하여 변경 내용을 덮어씁니다( 참조 sigaction()). 신호 캡처가 설치되어 있으면 signal()이런 일이 발생할지 확실하지 않습니다 .

Linux에서는 signal(2)단지더 이상 사용되지 않음호환 래퍼 sigaction(2), 이는 를 사용할 때도 발생합니다 signal(2).

관련 정보