환경은 1 process, multi-thread라 가정합니다.
그리고 각각의 sub-thread들은 recv 대기중에 있으며 저는 원하는 시간에 이들을 깨우기 위해 alarm()시스템 콜을 사용하려고 합니다.
(time out에서 일반적으로 쓰는 방법, 즉 select 대기나 SO_RCVTIMEO등은 사용할 수 없다고 가정합니다.)
그러나 문제는 alarm이라는 system call이 per-thread가 아닌 per-process라는데 문제가 있습니다.
가령, multi-thread환경에서
alarm(5);
recv(...);
alarm(0);
과 같은 코드를 작성하면 불행하게도 recv에서 대기하고 있던 여러개의 thread가 동시에 wake-up하기 때문에 원하는 바대로 동작할 수 없습니다.
alarm이 아닌 pthread_kill을 사용하는 경우에
pthread_kill(pthread_self(), SIGALRM);
recv(...);
와 같은 Code에서 보듯이 recv에서 대기하는 것이 불가능하게 됩니다.
그래서 결국은 alarm()을 이용하여 SIGALRM을 발생시키면서도 모든 thread가 아닌 특정 thread에서만 SIGALRM을 받을 수 있는 제 3의 방법이 있어야 합니다.
이런 경우를 직접 Coding해 보신 분이 계신지 궁금합니다.
고수의 친절한 가르침을 기대합니다.
===================================================================================================================
일단 multi-thread에서 가장 다루기 힘든 부분 중 하나가 signal 처리입니다. 힘든 건 둘째치고, platform에 따라서 제대로 동작하지 않을 수도 있습니다. 따라서 가능하면 signal을 쓰지 않도록 노력해보기 바랍니다. 그래도 꼭 signal을 써야만 한다면...
pthread_sigmask()를 써서 thread당 독립적으로 동작하는 signal mask를 등록하면 됩니다. 즉 signal을 받고자 하는 thread를 제외한 나머지 thread들에서 해당 signal을 블럭시키면 됩니다. (race condition을 방지하기 위해) thread를 처음 만들 때 자식 thread는 부모 thread로부터 signal mask를 상속받기 때문에, 자식 thread를 여러개 만들기 전에 먼저 블럭시킨다음 thread들을 만들고 나서 원하는 thread에서 unblock시키는 방법을 쓰는 것이 좋습니다.
노파심에서 말하지만 single threaded program에서 같은 목적으로 쓰는 sigprocmask()는 multi threaded program에서 쓰면 안됩니다.
자세한 것은 Programming with POSIX Threads에 잘 나와 있으니 참고하기 바랍니다.
'QnA' 카테고리의 다른 글
#if과 #if defined(= #ifdef) (0) | 2009.09.01 |
---|---|
제가 아는 한 CPU 보드 설계를 맨땅에서 하지 않습니다. (0) | 2009.08.26 |
sleep하는중에 alarm시그널이 catch되면 (0) | 2009.08.24 |
[Q/A] serial driver 중 line_discipline에 관한 질문입니다. (0) | 2009.08.21 |
임베디드 리눅스 시스템에서 데이터 버스의 공유...... (0) | 2009.08.13 |
WRITTEN BY
- RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.