pthread线程和信号

    所有的异步信号发到整个进程的所有线程(异步信号如kill, lwp_kill, sigsend, kill等调用产生的都是,异步信号也称为中断),而且所有线程共享信号的处理行为(即sigaction的设置,对于同一信号的设置,某一线程的更改会影响到所有线程)。但每个线程可以有自己的mask来阻止信号的发送,所以可以通过线程对mask的设置来决定信号发送到哪个线程。设置mask的函数为:
#include
int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset)
此外,线程可以通过sleep(超过指定时间或调用的进程/线程捕捉到某个信号并从信号处理程序返回时,sleep返回)或者sigwait来等待一个或多个信号发生。
#include
int pthread_sigwait(const sigset_t *restrict set, int *restrict signop);
给进程发送信号可以调用kill,同样给线程调用信号可以使用pthread_kill
#include
int pthread_kill(pthread_t thread, int signo);
可以发送一个0的signo来检查线程是否存在,如果信号的默认行为是终止进程(例如SIGARLM),那么把该信号发送给某个线程会杀掉整个进程的所有线程。
另外注意ALARM是进程资源,并且所有线程共享相同的ALARM,设置一个alarm()会发送SIGARLM信号给所有线程,所以他们不可能互补干扰的使用alarm()。
 
here comes an example:
   
   
   
   
  1. /*threadsig.c*/ 
  2. #include  
  3. #include  
  4. #include  
  5.  
  6. void sighandler(int signo); 
  7.  
  8. void * 
  9. thr1_fn(void *arg) 
  10.     pthread_t   tid = pthread_self(); 
  11.     int     rc; 
  12.  
  13.     printf("thread 1 with tid:%u\n", tid); 
  14.     rc = sleep(60); 
  15.     if (rc != 0) 
  16.         printf("thread 1... interrupted at %d second\n", 60 - rc); 
  17.     printf("thread 1 ends\n"); 
  18.     return NULL; 
  19.  
  20. void * 
  21. thr2_fn(void *arg) 
  22.     struct sigaction    action; 
  23.     pthread_t       tid = pthread_self();   
  24.     int         rc, err;   
  25.    
  26.     printf("thread 2 with tid:%u\n", tid);   
  27.      
  28.     action.sa_flags = 0; 
  29.     action.sa_handler = sighandler; 
  30.        
  31.     err = sigaction(SIGALRM, &action, NULL); 
  32.      
  33.     rc = sleep(60); 
  34.     if (rc != 0) 
  35.         printf("thread 2... interrupted at %d second\n", 60 - rc); 
  36.     printf("thread 2 ends\n"); 
  37.     return NULL; 
  38.  
  39. void * 
  40. thr3_fn(void *arg) 
  41.     pthread_t   tid = pthread_self();   
  42.     sigset_t    mask;   
  43.     int     rc, err;   
  44.    
  45.     printf("thread 3 with tid%u\n", tid); 
  46.  
  47.      
  48.     sigemptyset(&mask); /* 初始化mask信号集 */   
  49.    
  50.     sigaddset(&mask, SIGALRM);   
  51.     err = pthread_sigmask(SIG_BLOCK, &mask, NULL);   
  52.     if (err != 0)   
  53.     {   
  54.         printf("%d, %s/n", rc, strerror(rc));   
  55.         return NULL;   
  56.     } 
  57.    
  58.     rc = sleep(60); 
  59.         if (rc != 0) 
  60.                 printf("thread 3... interrupted at %d second\n", 60 - rc); 
  61.         printf("thread 3 ends\n"); 
  62.         return NULL; 
  63.  
  64.     return NULL; 
  65.  
  66. int 
  67. main(void
  68.     int     rc, err;   
  69.     pthread_t   thr1, thr2, thr3, thrm = pthread_self(); 
  70.  
  71.     printf("thread main with pid %u\n", (unsigned int)thrm); 
  72.     err = pthread_create(&thr1, NULL, thr1_fn, NULL); 
  73.     if (err != 0) { 
  74.         printf("error in creating pthread:%d\t%s\n",err, strerror(rc)); 
  75.         exit(1); 
  76.     } 
  77.  
  78.      
  79. /*  pthread_kill(thr1, SIGALRM);    send a SIGARLM signal to thr1 before thr2 set the signal handler, then the whole process will be terminated*/ 
  80.     err = pthread_create(&thr2, NULL, thr2_fn, NULL); 
  81.     if (err != 0) { 
  82.         printf("error in creating pthread:%d\t%s\n",err, strerror(rc)); 
  83.         exit(1); 
  84.     } 
  85.      
  86.     err = pthread_create(&thr3, NULL, thr3_fn, NULL); 
  87.     if (err != 0) { 
  88.         printf("error in creating pthread:%d\t%s\n",err, strerror(rc)); 
  89.         exit(1); 
  90.     } 
  91.  
  92.     sleep(3); 
  93.     pthread_kill(thr1, SIGALRM); 
  94.     pthread_kill(thr2, SIGALRM); 
  95.     pthread_kill(thr3, SIGALRM); 
  96.     pthread_join(thr1, NULL);   /*wait for the threads to complete.*/ 
  97.     pthread_join(thr2, NULL); 
  98.     pthread_join(thr3, NULL); 
  99.     printf("main ends\n"); 
  100.     return 0; 
  101.  
  102. void  
  103. sighandler(int signo) 
  104.     pthread_t   tid = pthread_self(); 
  105.      
  106.     printf("thread with pid:%u receive signo:%d\n", tid, signo); 
  107.     return

luffy@luffy-laptop:~/workspace/myapue$ ./threadsig 
thread main with pid 3557979936
thread 1 with tid:3549923072
thread 2 with tid:3541530368
thread 3 with tid3533137664
thread with pid:3549923072 receive signo:14
thread with pid:3541530368 receive signo:14
thread 2... interrupted at 3 second
thread 1... interrupted at 3 second
thread 1 ends
thread 2 ends #then wait for 27 seconds and thread-3 ends
thread 3 ends
main ends
 
    thr2设置的信号处理程序 sighandler也应用到其他线程,thr3由于设置mask所有阻塞了SIGARLM信号。

 
Reference:
APUE
线程信号 http://blog.csdn.net/copal/article/details/5454279