![다음 코드가 SIGINT 신호를 잠금 해제할 수 없는 이유](https://linux55.com/image/161150/%EB%8B%A4%EC%9D%8C%20%EC%BD%94%EB%93%9C%EA%B0%80%20SIGINT%20%EC%8B%A0%ED%98%B8%EB%A5%BC%20%EC%9E%A0%EA%B8%88%20%ED%95%B4%EC%A0%9C%ED%95%A0%20%EC%88%98%20%EC%97%86%EB%8A%94%20%EC%9D%B4%EC%9C%A0.png)
나는 Linux Signals를 시도하고 있습니다. 저는 다음과 같은 시나리오를 만들었습니다.
- 처음에는 모든
SIGINT
신호를 차단합니다sigprocmask()
. - 발신자가
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)
.