歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 《APUE》:同步信號處理

《APUE》:同步信號處理

日期:2017/3/1 10:09:12   编辑:Linux編程

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

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

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