리눅스 시그널을 연습하는 중에

dalant019의 이미지

리눅스 2.4를 사용하고 있습니다.

시그널이 큐잉이 되지 않음을 테스트하고 있는데

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

void sig_int(int);
void sig_usr(int);

int main()
{
char buf[255];
int i = 0;

if ((signal(SIGINT, sig_int)) == SIG_ERR)
{
perror("signal setting error : ");
exit(1);
}

if ((signal(SIGUSR2, sig_usr)) == SIG_ERR)
{
perror("signal setting error : ");
exit(1);
}

while (1)
{
printf("%d\n", i);
sleep(1);
i++;
}
}

void sig_int(int signo)
{
sleep(5);
fprintf(stderr, "SIGINT!\n");
fprintf(stderr, "SIGINT!!\n");
fprintf(stderr, "SIGINT!!!\n");
}

void sig_usr(int signo)
{
fprintf(stderr, "SIGUSR!!!\n");
}

위의 프로그램을 실행시킨 뒤
SIGINT(컨트롤 C)를 발생시킨 후 곧바로 SIGUSR2(다른 터미널에서 kill 명령)를 발생시켰읍니다.

sleep(5) 상태에서 바로 SIGUSR2를 받아서 SIGUSR를 호출한 뒤 큐잉 하지 않는다는 원리에 의해 SIGINT! SIGINT!! SIGINT!!!가 출력되지 않음을 예상했으나

.... TT
출력이 되네요...

리눅스 2.4 부터는 이문제를 해결한 건가요? 그러면 일반 시그널도 리어타임시그널과 같은 건가요?

궁금합니다.

wariua의 이미지

잘 동작하고 있는 거... 아닐까요-.-?
큐잉이 되지 않음이라는 말로 의미하시는 게 한 시그널 핸들러가 실행되고 있는 중 다른 시그널이 도착하면 즉시 처리되거나 차단되지, 줄줄이 사탕으로 대기를 하고 있지 않는다라는 의미라면, 잘 동작하고 있는 것 같은데요- (큐잉이 되는 대신 stacking이 되고 있기는 합니다만:) )

1. sig_int()가 호출되고, 그 안에서 sleep()이 호출되고,
2. 그 와중에 SIGUSR2가 날아와서 (대기큐에 추가되는 대신 즉시) sig_usr()가 호출되고, "SIGUSR!!!"이 출력되고, sig_usr()가 완료되고,
3. 다시 sleep()로 돌아가고, sleep()이 반환되고, "SIGINT! SIGINT!! SIGINT!!!"를 출력하고, sig_int()가 완료되고...

혹시 1과 2까지는 동작을 하되 3은 동작하지 않는 걸 생각하시는 건가요?

$PWD `date`

익명 사용자의 이미지

signal의 특성 상 함수와는 다르게 한 시그널을 처리할 때(핸드러가 호출됨) 다른 시그널이 발생하면 먼저 수행되고 있던 핸들러를 중단 한뒤 새로이 발생한 시그널의 핸들러를 실행하게 되고 실행 후 전 핸들러의 중단된 지점으로 돌아가지 않는다고 배웠습니다.(그게 시그널의 단점이라고)

근데 테스트 해보니 중단된 지점으로 돌아가서요...

혹시나 리눅스 2.4가 이 문제를 해결했는지 알고싶었습니다.

서지훈의 이미지

이걸 보면은 signal을 받는 순간...
그지점의 주소를 stack에 저장하고...
마지막 sigusr2 를 받고..
stack에 쌓여 있는 주소들을 뱃어 내다 보니...
SIGINT 도 출력이 되는게 정상이지 싶습니다.

signal hander 함수도 어딘가로 리턴을 해야 하는데...
역시나 signal이 호출된 밖에 돌아 갈데가 없군요.

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

wariua의 이미지

일반적인 시그널에서 queueing을 하지 않고 실시간 시그널에서 queueing을 한다라는 것과 말씀하신 문제와는 좀 다른 문제인 듯 합니다. 기존 시그널 메커니즘에서는 짧은 간격으로 연속적으로 도착한 시그널 중 일부가 유실되는 문제가 있고, 그 문제를 해결하기 위해 도착 시그널들을 차곡차곡 queueing 해주는 실시간 시그널이 등장한 것...인 것 같습니다;; (실시간 시그널에 대해선 저도 모릅니다. POSIX 표준에 그런 내용이 있다고는 합니다;; )

말씀하신 문제는 "시그널 핸들러가 실행중일 때 다른 시그널을 받아서 두 번째 시그널 핸들러가 실행된 경우, 두 번쨰 시그널 핸들러의 실행이 완료된 후 첫 번째 시그널 핸들러의 실행이 재개되는가" 하는 것인데... GNU C Library Manual에서는 질문만 해놓고 대답은 하지 않는 만행을 저지르고 있습니다.

하지만, 다른 시그널에게 인터럽트 된 시그널 핸들러의 실행이 재개되지 않는다면 참... 곤란하지 않을까요? 계란프라이를 만들고 있는데 전화가 왔으면 전화를 받은 후 다시 프라이팬으로 가야 합니다. 안 그럼 계란프라이 못 먹습니다 :oops:

$PWD `date`

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.