[질문] thread 생성 후 signal 처리

morison77의 이미지

thread 를 두개 만들어서 돌리고 있는데
(표현이 맞는지는 모르겠지만 메인 쓰레드, 쓰레드 1, 쓰레드 2 로 계속
표현하겠습니다)

메인 쓰레드는 1초간 슬립하면서 무한 루프를 돌고 있고요

쓰레드 1과 2도 메인쓰레드와 마찬가지로 1초간 슬립하면서 무한 루프를
돌고 있습니다.

시그널들에 대해선 시그널 핸들러를 만들어 자원 정리를 해주고 끝나고 있고요

헌데 제가 알기로는 시그널이 오면 쓰레드 1과 2는
루프를 시그널 핸들러가 마치고 프로그램이 끝날때 까지
계속 돌고 있고 메인쓰레드에서 루프가 빠져 나가서
시그널을 처리하게 되는지 알고 있었는데

원인은 모르겠지만 쓰레드 1 혹은 2에서 간혹 시그널이 처리되버리고
메인 쓰레드의 루프는 계속 돌고 있는 것 같습니다.

혹시 이에 대해 좀 설명좀 해주시고 해결 방법이 있다면 알려주실 수 있을까여?^^

shkwon81의 이미지

Pthread 에서는 한 프로세스로 보내진 시그널은 프로세스 내에서 해당 시그널을 블록하고 있지 않은 어떠한 쓰레드라도 받을 수 있습니다. (즉, 어떤 쓰레드가 받을지 모른다는 얘기입니다.)

따라서 원하는 동작을 구현하시려면,
모든 쓰레드가 해당 시그널을 블록하고, 시그널을 처리하고자 하는 쓰레드가
sigwait() 함수를 사용하여 시그널을 처리하기 원하는 위치(예를 들면 루프의 순환마다 한번씩) 동기적으로 시그널 발생 여부를 검사하고 핸들러를 수행하는 방식을 쓰시는 것이 좋습니다.

가급적, 쓰레드 프로그래밍을 하실 때는 시그널의 사용을 자제하시는 편이 좋습니다 ^^

verena의 이미지

참고로 pthread를 이용할 경우

void actionForSegmentationFault(int sig)
{
    printf("%d\n", pthread_self());
    pthread_exit(0);
}

void* threadRootine(void* arg)
{
    signal(11, actionForSegmentationFault);

    printf("%d thread start\n", pthread_self());

    int* p = 0;

    printf("%d\n", *p); //segmentation fault 일으키기...
    .....
}

이렇게 하시면 쓰레드 단위로 시그널을 처리합니다.

즉 signal의 수행 단위는 thread입니다. 그리고 actionForSegmentationFault는 signal(11, actionForSegmentationFault);을 수행한 쓰레드가 수행하게 됩니다.

확인은 위의 코드를 수행해보시기 바랍니다.

shkwon81의 이미지

Quote:
즉 signal의 수행 단위는 thread입니다. 그리고 actionForSegmentationFault는 signal(11, actionForSegmentationFault);을 수행한 쓰레드가 수행하게 됩니다.

모든 시그널의 동작 단위는 "프로세스"입니다.

따라서, signal() 함수나 sigaction() 함수로 시그널 핸들러를 변경하면 그 대상은 "프로세스"가 됩니다. 즉, 프로세스 전체에 대해 시그널 핸들러가 변경되는 것이죠

다만 signal mask는 프로세스가 아니라 쓰레드 별로 설정이 가능합니다. 이 때 사용하는 함수가 pthread_sigmask() 입니다. 즉, 특정 시그널을 어떤 쓰레드에 대해서는 블록시키고 어떤 쓰레드에 대해서는 블록시키지 않는 것은 가능합니다.

단지 예로 들어 주신 코드에서

printf("%d\n", *p); //segmentation fault 일으키기

위 코드에서 발생한 segmentation fault가 위 코드를 수행한 쓰레드에서 처리된 이유는, SIGSEGV가 동기적 시그널이기 때문입니다. 이에 대해서는 다음 링크를 참조하세요..

http://bbs.kldp.org/viewtopic.php?p=64923&highlight=#64923

http://groups.google.co.kr/groups?hl=ko&lr=&ie=UTF-8&inlang=ko&newwindow=1&th=71b56c79ab47cbb2&rnum=1

다시 말하지만, 비동기적 시그널이라면 해당 시그널을 블록하지 않은 쓰레드 중 누가 시그널을 처리할지는 절대 보장되지 않는 사항입니다.

verena의 이미지

헉...

그건 단순히 예제였구요... 전 지금까지 그렇게 써왔었는데[저의 경우엔 시그널 처리는 segmentation fault외엔 사용을 안했거던요...].... 잘 작동을... 음 그러면 역시 그런 문제의 소지가 있겠군요...

아 signal()대신 pthread_sigmask()를 쓰면 되는군요. 근데 처음에 할땐 이걸 사용했었는데 안되길레... 다시한번 더 정확하게 써 봐야겠군요.

매번 많은 도움을 받고 갑니다. ^^

댓글 달기

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 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • 사용할 수 있는 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>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • You can use Textile markup to format text.
  • 사용할 수 있는 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>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 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>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.