Wednesday, May 21, 2008

Signals, signal block with masking

프로세스는 여러개의 signal을 block 시킬 수 있는데,이 때 sigprocmask()를 사용한다.

#include <signal.h>
int sigprocmask (int how, const sigset_t *set,
sigset_t *oldset);

how에 SIG_BLOCK 를 주면 sigset에 해당하는 signal들이 block되고, SIG_UNBLOCK을 주면 해제된다. SIG_SETMASK는 ... 잘 모르겠다 ㅡㅡ; set이 NULL 인 경우에는 현재 block 되어 있는 signal들이 oldset에 찍혀 나온다.

이런식으로 block한 signal들은 unblock하면 프로세스에 전달되는데, pending된 signal들은 sigpending(sigset_t *set)을 통해 확인할 수 있다. 일반적으로 signal을 고려한 critical section의 처리는 아래와 같은 순서로 진행된다.

  • sigprocmask()로 특정 signal들을 block한다.

  • critical section 을 처리한다.

  • sigsuspend()로 block한 signal 들이 처리될 때 까지 기다린다.


이러한 식으로 signal set을 통해 간단한 코드를 짜보면,

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

void sig_handler(int signo)
{
fprintf(stderr, "signal caught : %s\n", sys_siglist[signo]);
return;
}

int main()
{
sigset_t sigset;
sigset_t sigset_old;
sigset_t sigset_test;

if (signal(SIGINT, sig_handler) == SIG_ERR) {
fprintf(stderr, "SIGINT handle can't be registered\n");
}
if (signal(SIGQUIT, sig_handler) == SIG_ERR) {
fprintf(stderr, "SIGINT handle can't be registered\n");
}

sigemptyset(&sigset);
sigaddset(&sigset, SIGQUIT);
sigprocmask(SIG_BLOCK, &sigset, &sigset_old);
pause();
sigpending(&sigset_test);
if (sigismember(&sigset_test, SIGQUIT))
printf("SIGQUIT is pending\n");
sigsuspend(&sigset_old);
//sigprocmask(SIG_UNBLOCK, &sigset, NULL);
return;
}


SIGINT, SIGQUIT 핸들러를 등록하고, sigset에 SIGQUIT을 넣고 sigprocmask로 블럭한다음 pause()로 signal을 기다린다(SIGQUIT이 block되어 있기 때문에 Ctrl+\ 을 눌러도 반응이 없다). Ctrl-c를 누르면 block되지 않은 signal 이므로 pause()를 빠져나오고 handler가 호출된다. 그리고 sigpending()에서 현재 pending 된 signal을 확인한다. Ctrl+c전에 Ctrl+\를 눌렀다면 SIGQUIT이 pending되었다고 나오게 된다. 그리고 마지막 두줄이 중요한데, sigsuspend(&sigset_old) 를 호출하면 프로세스가 sigset_old에 있는 SIGQUIT signal이 일어나서 처리 될때까지 대기한다(때문에 SIGQUIT이 들어오지 않으면 계속 기다리고 있는다). sigsuspend 대신에 sigprocmask 로 UNBLOCK하면 그 순간 pending되어 있는 signal 이 프로세스에 전달되는데, pending 되어 있는 signal이 없으면 그냥 넘어간다. 즉 sigsuspend()를 쓰면 signal이 일어날때까지 기다리고, sigprocmask UNBLOCK을 쓰면 signal이 있을 때 handler가 호출되고 없으면 그냥 넘어가는 차이가 있다.

No comments:

Post a Comment