2009년 10월 22일
thread programming
posix thread 와 관련하여 signal handling을 해야하는 일이 있어서...
(뭐.. 정확히는 data handling하는 부분에 있어서 thread로 동작시 강제 종료할 경우 data가 틀어지는 문제가 있어서... 흑..ㅠㅠ)
기존의 sigprocmask대신에 pthread_sigmask를 사용하는데.. 새로 알게 된 사실들....
1. thread 생성 이전에 signal 을 설정해줘야 한다...
아래의 sample code에서와 같이 SIG_BLOCK을 thread 생성전에 해줘야 thread에서 해당 signal 이 block된다...
심지어.. thread 생성전에 signal을 설정해줘도.. SIG_UNBLOCK을 해두면.. 무효.. -_-
2. pthread_sigmask라고 해도.. thread별로 signal을 받는게 아니므로.. 큰 의미는 모르겠음.. -_-;;
아래 샘플코드는 테스트한 내용을 전부 해둔거라 지저분하지만.. 뭐.. 언젠가 또 볼일이 있을지도...ㅋ
결론: thread로 바꿀시에는 심각하게 signal이라던가.. variable등을 심각하게 고려해 concurrency control에 문제가 없는지 다시 한번 고민해볼지어다..ㅠㅠ
<1>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <time.h>
sigset_t mdgBset, mdgOset;
void *sub(void)
{
char tmp[1024];
sigset_t newmask;
struct timespec st;
sigemptyset(&newmask);
sigaddset(&newmask, SIGINT);
#if 1
pthread_sigmask(SIG_UNBLOCK, &newmask, 0);
#if 0
if(pthread_sigmask(SIG_BLOCK, &mdgBset, 0) != 0)
fprintf(stderr, "[%s: %d]\n", __FILE__, __LINE__);
#endif
printf("yo man~!\n");
fgets(tmp, sizeof(tmp), stdin);
pthread_sigmask(SIG_BLOCK, &newmask, 0);
st.tv_sec = 3;
st.tv_nsec = 0;
printf("end man~!\n");
fgets(tmp, sizeof(tmp), stdin);
//nanosleep(&st, NULL);
#if 0
if(pthread_sigmask(SIG_SETMASK, &mdgOset, 0) != 0)
fprintf(stderr, "[%s: %d]\n", __FILE__, __LINE__);
#endif
printf("done man~!\n");
fgets(tmp, sizeof(tmp), stdin);
pthread_sigmask(SIG_UNBLOCK, &newmask, 0);
printf("restart man~!\n");
fgets(tmp, sizeof(tmp), stdin);
#else
sigprocmask(SIG_UNBLOCK, &newmask, 0);
#if 0
if(pthread_sigmask(SIG_BLOCK, &mdgBset, 0) != 0)
fprintf(stderr, "[%s: %d]\n", __FILE__, __LINE__);
#endif
printf("yo man~!\n");
fgets(tmp, sizeof(tmp), stdin);
sigprocmask(SIG_BLOCK, &newmask, 0);
printf("end man~!\n");
fgets(tmp, sizeof(tmp), stdin);
#if 0
if(pthread_sigmask(SIG_SETMASK, &mdgOset, 0) != 0)
fprintf(stderr, "[%s: %d]\n", __FILE__, __LINE__);
#endif
printf("done man~!\n");
fgets(tmp, sizeof(tmp), stdin);
sigprocmask(SIG_UNBLOCK, &newmask, 0);
printf("restart man~!\n");
fgets(tmp, sizeof(tmp), stdin);
#endif
}
void sub_set()
{
sigemptyset(&mdgBset);
sigaddset(&mdgBset, SIGINT);
#if 1
if(pthread_sigmask(SIG_SETMASK, &mdgBset, &mdgOset) != 0)
{
fprintf(stderr, "[%s: %d]\n", __FILE__, __LINE__);
}
if(pthread_sigmask(SIG_SETMASK, &mdgOset, 0) != 0)
{
fprintf(stderr, "[%s: %d]\n", __FILE__, __LINE__);
}
#if 1
if(pthread_sigmask(SIG_BLOCK, &mdgBset, 0) != 0)
fprintf(stderr, "[%s: %d]\n", __FILE__, __LINE__);
// pthread_sigmask(SIG_UNBLOCK, &mdgBset, 0);
#endif
#else
sigprocmask(SIG_SETMASK, &mdgBset, &mdgOset);
sigprocmask(SIG_SETMASK, &mdgOset, NULL);
sigprocmask(SIG_BLOCK, &mdgBset, NULL);
// sigprocmask(SIG_SETMASK, &mdgOset, NULL);
#endif
}
int main(int argc, char* argv[])
{
pthread_t tid[4];
int iIdx;
sub_set();
// pthread_sigmask(SIG_UNBLOCK, &mdgBset, 0);
#if 1
for(iIdx = 0; iIdx < 1; iIdx++)
pthread_create(&tid[iIdx], NULL, sub, NULL);
for(iIdx = 0; iIdx < 1; iIdx++)
pthread_join(tid[iIdx], NULL);
#else
sub();
#endif
}
# by | 2009/10/22 18:00 | IT Life | 트랙백 | 덧글(1)








☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]