分享

C语言中signal函数简介及使用

 XeonGate 2019-10-24

https://blog.csdn.net/fengbingchun/article/details/92074191

signal.h是C标准函数库中的信号处理部分,定义了程序执行时如何处理不同的信号。信号用作进程间通信,报告异常行为(如除零)、用户的一些按键组合(如同时按下Ctrl与C键,产生信号SIGINT)。C++中的对应头文件是csignal。

C语言标准定义了6个信号,都定义在signal.h头文件中:

(1). SIGABRT:程序异常中止,如调用abort函数。

(2). SIGFPE:算术运算出错,如除数为0或溢出。

(3). SIGILL:非法函数映像,如非法指令。

(4). SIGINT:交互的用户按键请求,如同时按下Ctrl+C键。

(5). SIGSEGV:无效内存访问,段错误。

(6). SIGTERM:程序的中止请求。

signal.h可能还定义了其它信号,这依赖于具体实现。例如,类Unix系统还定义了15个以上的信号。Visual C++的C标准库只支持C语言标准规定的6个信号,即对信号处理只提供最小的支持。

signal函数:该函数设置一个函数(回调函数)来处理捕获到异常信号时需要执行的操作,其函数声明方式如下:

  1. // Type of a signal handler
  2. typedef void (*__sighandler_t)(int);
  3. __sighandler_t signal(int __sig, __sighandler_t __handler);

下面是测试代码:

  1. #include "signal.hpp"
  2. #include <signal.h>
  3. #include <string>
  4. #include <thread>
  5. #include <chrono>
  6. namespace signal_ {
  7. namespace {
  8. bool flag = true;
  9. void process_exit(int sig)
  10. {
  11. switch (sig) {
  12. case SIGINT:
  13. fprintf(stderr, "process exit: SIGINT: value: %d\n", sig);
  14. break;
  15. case SIGFPE:
  16. fprintf(stderr, "process exit: SIGFPE: value: %d\n", sig);
  17. break;
  18. case SIGABRT:
  19. fprintf(stderr, "process exit: SIGABRT: value: %d\n", sig);
  20. break;
  21. case SIGILL:
  22. fprintf(stderr, "process exit: SIGILL: value: %d\n", sig);
  23. break;
  24. case SIGSEGV:
  25. fprintf(stderr, "process exit: SIGSEGV: value: %d\n", sig);
  26. break;
  27. case SIGTERM:
  28. fprintf(stderr, "process exit: SIGTERM: value: %d\n", sig);
  29. break;
  30. default:
  31. fprintf(stderr, "process exit: value: %d\n", sig);
  32. break;
  33. }
  34. flag = false;
  35. }
  36. void wait_ctrl_c()
  37. {
  38. while (flag) {
  39. std::this_thread::sleep_for(std::chrono::seconds(2));
  40. fprintf(stdout, "please press to exit: Ctrl + c ... \n");
  41. }
  42. }
  43. void signal_type()
  44. {
  45. signal(SIGINT, process_exit);
  46. signal(SIGFPE, process_exit);
  47. signal(SIGILL, process_exit);
  48. signal(SIGABRT, process_exit);
  49. signal(SIGSEGV, process_exit);
  50. signal(SIGTERM, process_exit);
  51. }
  52. void signal_sigill(int)
  53. {
  54. fprintf(stdout, "caught SIGILL signal\n");
  55. }
  56. void signal_sigterm(int)
  57. {
  58. fprintf(stdout, "caught SIGTERM signal\n");
  59. }
  60. } // namespace
  61. int test_signal_SIGINT()
  62. {
  63. signal_type();
  64. std::thread th(wait_ctrl_c);
  65. th.join();
  66. return 0;
  67. }
  68. int test_signal_SIGILL()
  69. {
  70. //signal_type();
  71. if (signal(SIGILL, signal_sigill) == SIG_ERR) {
  72. fprintf(stdout, "cannot handle SIGILL\n");
  73. } else {
  74. fprintf(stdout, "yyyyy\n");
  75. }
  76. return 0;
  77. }
  78. int test_signal_SIGFPE()
  79. {
  80. signal_type();
  81. int a = 1, b = 0, c;
  82. c = a / b;
  83. fprintf(stdout, "c = %d\n", c);
  84. return 0;
  85. }
  86. int test_signal_SIGSEGV()
  87. {
  88. signal_type();
  89. int a[3] = {0};
  90. fprintf(stdout, "a[3] = %d\n", a[-1111111]);
  91. return 0;
  92. }
  93. int test_signal_SIGTERM()
  94. {
  95. //signal_type();
  96. if (signal(SIGTERM, signal_sigterm) == SIG_ERR) {
  97. fprintf(stdout, "cannot handle SIGTERM\n");
  98. } else {
  99. fprintf(stdout, "xxxxx\n");
  100. }
  101. return 0;
  102. }
  103. int test_signal_SIGABRT()
  104. {
  105. signal_type();
  106. abort();
  107. return 0;
  108. }
  109. } // namespace signal_

测试test_signal_SIGINT时的输出结果如下:

GitHub: https://github.com/fengbingchun/Messy_Test 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多