信号集的操作

信号集的初始操作

信号集 : 能够表示多个信号的数据类型

  
  
  1. #include <signal.h>
  2. // 以下函数, 成功, 返回 0; 失败, 返回 -1.
  3. int sigemptyset(sigset_t *set) // 清除信号集中的所以信号
  4. int sigfillset(sigset_t *set) // 初始化set信号集中的信号, 并把所有该程序的信号加入到信号集中
  5. int sigaddset(sigset_t *set, int signo) // 添加signo信号到信号集中
  6. int sigdelset(sigset_t *set, int signo) // 信号集中删除signo信号
  7. // 成功,返回 1; 失败, 返回 0.
  8. int sigismember(const sigset_t *set, int signo) // 测试一个指定的位

在所有应用程序使用信号集之前, 要对信号集调用sigemptyset和sigfillset一次.


sigprocmask 函数

  
  
  1. #include <signal.h>
  2. int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset)
  3. // 成功, 返回 0; 失败, 返回 -1.

关于sigpromask()函数的各个参数的取值对函数功能的影响很重要, 这个函数也是signal信号集很重要的一部分.

how可设置的参数为:SIG_BLOCK, SIG_UNBLOCK,SIG_SETMASK

SIG_BLOCK :按照参数 set 提供的屏蔽字,屏蔽信号。并将原信号屏蔽保存到oldset中。
SIG_UNBLOCK :按照参数 set 提供的屏蔽字进行信号的解除屏蔽。针对set中的信号进行解屏。
SIG_SETMASK : 按照参数 set 提供的信号设置重新设置系统信号。即, 该进程新的屏蔽字是 set 的值。

关于常见的sigprocmask()函数的操作

  1. sigprocmask(SIG_BLOCK, set, NULL)
    • 屏蔽set中保存的信号
    • 可更新程序的信号集
  2. sigprocmask(SIG_UNBLOCK, set, NULL)
    • 当前的程序中set中包含的信号全部取消屏蔽
  3. sigprocmask(SIG_SETMASK, set, NULL)
    • 程序的屏蔽字为set信号集中包含的信号
    • 可更新程序的信号集
 
 
  1. /*************************************************************************
  2. > File Name: t.cpp
  3. > Author: Function_Dou
  4. > Mail:
  5. > Created Time: 2018年02月03日 星期六 17时58分22秒
  6. ************************************************************************/
  7. #include <stdio.h>
  8. #include <signal.h>
  9. #include "apue.h"
  10. void checkset(int i);
  11. int main()
  12. {
  13. sigset_t blockset;
  14. sigemptyset(&blockset);
  15. // 添加两个信号进入信号集中
  16. sigaddset(&blockset,SIGINT);
  17. sigaddset(&blockset,SIGTSTP);
  18. // 测试信号集中由SIGINT信号了
  19. if(sigismember(&blockset,SIGINT))
  20. printf("SIGINT\n\n");
  21. // 没有信号输出是因为当前的信号集还是NULL(空的)
  22. checkset(0);
  23. // 将blockset信号集变为当前程序的信号集
  24. sigprocmask(SIG_SETMASK, &blockset,NULL);
  25. if(sigismember(&blockset,SIGINT))
  26. printf("SIGINT\n\n");
  27. // 现在的信号集不再为NULL了.
  28. checkset(1);
  29. sigaddset(&blockset,SIGTERM);
  30. // sigprocmask(SIG_SETMASK, &blockset,NULL);
  31. // 此时的SIG_BLOCK意义跟SIG_SETMASK意义一样, 都是更新当前blockset信号集:
  32. sigprocmask(SIG_BLOCK,&blockset,NULL);
  33. checkset(2);
  34. // SIG_UNBLOCK 将blockset 信号集全部取消屏蔽. 也就是程序取消了对信号集的屏蔽了, 但是blockset中的信号还是存在的.
  35. sigprocmask(SIG_UNBLOCK,&blockset,NULL);
  36. if(sigismember(&blockset,SIGTERM))
  37. printf("SIGTERM\n");
  38. if(sigismember(&blockset,SIGINT))
  39. printf("SIGINT\n");
  40. if(sigismember(&blockset,SIGTSTP))
  41. printf("SIGSTP\n\n");
  42. // 检测到程序中的信号屏蔽已经没有了.
  43. checkset(3);
  44. if(sigismember(&blockset,SIGTERM))
  45. printf("SIGTERM\n");
  46. if(sigismember(&blockset,SIGINT))
  47. printf("SIGINT\n");
  48. if(sigismember(&blockset,SIGTSTP))
  49. printf("SIGTSTP\n");
  50. checkset(4);
  51. }
  52. void checkset(int i)
  53. {
  54. sigset_t set;
  55. printf("check set start:%d\n", i);
  56. if(sigprocmask(SIG_SETMASK, NULL, &set) < -1)
  57. {
  58. printf("check set sig procmask error!!\n");
  59. exit(0);
  60. }
  61. if(sigismember(&set,SIGINT))
  62. printf("SIGINT\n");
  63. if(sigismember(&set,SIGTSTP))
  64. printf("SIGTSTP\n");
  65. if(sigismember(&set,SIGTERM))
  66. printf("SIGTERM\n");
  67. printf("check set end\n\n");
  68. }

运行结果

 
 
  1. [root@localhost Signal]# ./a.out
  2. SIGINT
  3. check set start:0
  4. check set end
  5. SIGINT
  6. check set start:1
  7. SIGINT
  8. SIGTSTP
  9. check set end
  10. check set start:2
  11. SIGINT
  12. SIGTSTP
  13. SIGTERM
  14. check set end
  15. SIGTERM
  16. SIGINT
  17. SIGSTP
  18. check set start:3
  19. check set end
  20. SIGTERM
  21. SIGINT
  22. SIGTSTP
  23. check set start:4
  24. check set end

关于sigprocmask()函数理解, 在此我还写了一个更简单的程序, 方便理解程序中的屏蔽信号

 
 
  1. /*************************************************************************
  2. > File Name: z.cpp
  3. > Author: Function_Dou
  4. > Mail:
  5. > Created Time: 2018年02月03日 星期六 22时55分58秒
  6. ************************************************************************/
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <signal.h>
  10. static void Fun(sigset_t sigset)
  11. {
  12. if(sigismember(&sigset, SIGSEGV))
  13. printf("SIGEGV\n");
  14. if(sigismember(&sigset, SIGINT))
  15. printf("SIGINT\n");
  16. if(sigismember(&sigset, SIGTERM))
  17. printf("SIGTERM\n");
  18. if(sigismember(&sigset, SIGALRM))
  19. printf("SIGALRM\n");
  20. }
  21. int main()
  22. {
  23. sigset_t new_sigset, old_sigset;
  24. sigemptyset(&new_sigset);
  25. sigemptyset(&old_sigset);
  26. sigaddset(&new_sigset, SIGSEGV);
  27. sigaddset(&new_sigset, SIGINT);
  28. sigaddset(&new_sigset, SIGTERM);
  29. printf("1 new_sigset\n");
  30. Fun(new_sigset);
  31. printf("\n\n");
  32. sigprocmask(SIG_BLOCK, &new_sigset, &old_sigset);
  33. printf("2 old_sigset\n");
  34. Fun(old_sigset);
  35. printf("\n\n");
  36. printf("3 new_sigset\n");
  37. Fun(new_sigset);
  38. printf("\n\n");
  39. // sigaddset(&old_sigset, SIGALRM);
  40. sigaddset(&new_sigset, SIGALRM);
  41. sigprocmask(SIG_BLOCK, &new_sigset, &old_sigset);
  42. printf("4 old_sigset\n");
  43. Fun(old_sigset);
  44. printf("\n\n");
  45. printf("5 new_sigset\n");
  46. Fun(new_sigset);
  47. printf("\n\n");
  48. // 取消new_sigset中的信号屏蔽, 此时程序的信号集为NULL
  49. sigprocmask(SIG_UNBLOCK, &new_sigset, &old_sigset);
  50. printf("6 old_sigset\n");
  51. Fun(old_sigset);
  52. printf("\n\n");
  53. printf("7 new_sigset\n");
  54. Fun(new_sigset);
  55. printf("\n\n");
  56. // 这里old_sigset信号集中的信号为NULL, 因为上次程序的屏蔽字为NULL
  57. sigprocmask(SIG_SETMASK, &new_sigset, &old_sigset);
  58. printf("8 old_sigset\n");
  59. Fun(old_sigset);
  60. printf("\n\n");
  61. printf("9 new_sigset\n");
  62. Fun(new_sigset);
  63. printf("\n\n");
  64. exit(0);
  65. }

运行结果

 
 
  1. [root@localhost Signal]# ./a.out
  2. 1 new_sigset
  3. SIGEGV
  4. SIGINT
  5. SIGTERM
  6. 2 old_sigset
  7. 3 new_sigset
  8. SIGEGV
  9. SIGINT
  10. SIGTERM
  11. 4 old_sigset
  12. SIGEGV
  13. SIGINT
  14. SIGTERM
  15. 5 new_sigset
  16. SIGEGV
  17. SIGINT
  18. SIGTERM
  19. SIGALRM
  20. 6 old_sigset
  21. SIGEGV
  22. SIGINT
  23. SIGTERM
  24. SIGALRM
  25. 7 new_sigset
  26. SIGEGV
  27. SIGINT
  28. SIGTERM
  29. SIGALRM
  30. 8 old_sigset
  31. 9 new_sigset
  32. SIGEGV
  33. SIGINT
  34. SIGTERM
  35. SIGALRM

写了这么多的代码, 就是为了方便理解sigprocmask()函数各个参数的意义, 以及基础的运用.
希望对你有所帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值