歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

《APUE》:同步信號處理

《Unix環境高級編程》這本書附帶了許多短小精美的小程序,我在閱讀此書的時候,將書上的代碼按照自己的理解重寫了一遍(大部分是抄書上的),加深一下自己的理解(純看書太困了,呵呵)。此例子在Ubuntu 10.04上測試通過。

相關鏈接

  • 《UNIX環境高級編程》(第二版)apue.h的錯誤 http://www.linuxidc.com/Linux/2011-04/34662.htm
  • Unix環境高級編程 源代碼地址 http://www.linuxidc.com/Linux/2011-04/34826.htm

程序簡介:在多線程程序中等侍信號設置標志,從而讓主程序退出。唯一可運行的控制線程應該是主線程和信號處理程序,所以阻塞信號足以避免錯失標志的修改。另外在線程中,需要使用互斥量來保護標志。以下這個程序演示了這方面的內容。

  1. //《APUE》程序12-6:同步信號處理   
  2. #include <stdio.h>   
  3. #include <stdlib.h>   
  4. #include <unistd.h>   
  5. #include <signal.h>   
  6. #include <pthread.h>   
  7.   
  8. int quitflag;  
  9. sigset_t mask;  
  10.   
  11. pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;  
  12. pthread_cond_t wait = PTHREAD_COND_INITIALIZER;  
  13.   
  14. void *thr_fn(void *arg)  
  15. {  
  16.     int signo;  
  17.     while(1)  
  18.     {  
  19.         //設置阻塞信號集   
  20.         sigwait(&mask, &signo);  
  21.         switch(signo)  
  22.         {  
  23.             //收到中斷信號以後   
  24.         case SIGINT:  
  25.             printf("\ninterrupt\n");  
  26.             break;  
  27.   
  28.             //收到退出信號以後   
  29.         case SIGQUIT:  
  30.             pthread_mutex_lock(&lock);  
  31.             quitflag = 1;  
  32.             pthread_mutex_unlock(&lock);  
  33.             pthread_cond_signal(&wait);  
  34.             return 0;  
  35.   
  36.         default:  
  37.             printf("unexpected signal %d\n", signo);  
  38.             exit(1);  
  39.         }  
  40.     }  
  41. }  
  42.   
  43. int main(void)  
  44. {  
  45.     sigset_t oldmask;  
  46.     pthread_t tid;  
  47.   
  48.     sigemptyset(&mask);  
  49.     sigaddset(&mask, SIGINT);  
  50.     sigaddset(&mask, SIGQUIT);  
  51.   
  52.     pthread_sigmask(SIG_BLOCK, &mask, &oldmask);  
  53.     pthread_create(&tid, NULL, thr_fn, 0);  
  54.   
  55.     /* 
  56.     經典的UNIX條件鎖三步曲: 
  57.     1。使用pthread_cond_wait前要先加鎖 
  58.     2。pthread_cond_wait內部會解鎖,然後等待條件變量被其它線程激活 
  59.     3。pthread_cond_wait被激活後會再自動加鎖 
  60.     (所以還要我們視情況而決定是否手動解鎖) 
  61.     */  
  62.     pthread_mutex_lock(&lock);  
  63.     while( 0 == quitflag )  
  64.         pthread_cond_wait(&wait, &lock);  
  65.     pthread_mutex_unlock(&lock);  
  66.   
  67.     //收到退出信號,但現在這個信號是阻塞的   
  68.     quitflag = 0;  
  69.     //重置阻塞信號集(讓程序退出)   
  70.     sigprocmask(SIG_SETMASK, &oldmask, NULL);  
  71.     return 0;  
  72. }  

運行示例(紅色字體的為輸入):

www.linuxidc.com @ubuntu:~/code$gcc temp.c -lpthread -o temp
www.linuxidc.com @ubuntu:~/code$ ./temp
^C                              #輸入中斷字符(ctrl+C)
interrupt
^C                              #輸入中斷字符(ctrl+C)
interrupt
^C                              #輸入中斷字符(ctrl+C)
interrupt
^\                                #輸入退出字符(ctrl+\)

Copyright © Linux教程網 All Rights Reserved