C++ 处理 Kill 信号、Ctrl+C信号

  1. 来自: http://blog.csdn.net/xian0617/article/details/6689357
  2. /*
  3. * WaitQuitSignal.h
  4. *
  5. *  Created on: Aug 14, 2011
  6. *      Author: xian0617
  7. */ 
  8.  
  9. #ifndef WAITQUITSIGNAL_H_ 
  10. #define WAITQUITSIGNAL_H_ 
  11. #include <signal.h> 
  12. #include <time.h> 
  13. class WaitQuitSignal { 
  14. public
  15.     static void init(); 
  16.     static bool wait(bool&flag); 
  17. private
  18.     static sigset_t m_wait_mask; 
  19.     static struct timespec m_time; 
  20. }; 
  21.  
  22. #endif /* WAITQUITSIGNAL_H_ */ 


  1. /*
  2. * WaitQuitSignal.cpp
  3. *
  4. * Linux下的线程实质上是轻量级进程(light weighted process),线程生成时会生成对应的进程控制结构,
  5. * 只是该结构与父线程的进程控制结构共享了同一个进程内存空间。 同时新线程的进程控制结构将从父线程(进程)
  6. * 处复制得到同样的进程信息,如打开文件列表和信号阻塞掩码等。由于我们是在子线程生成之后修改了信号阻塞掩
  7. * 码,此刻子线程使用的是主线程原有的进程信息,因此子线程仍然会对SIGINT和SIGTERM信号进行反应,因此当
  8. * 我们用Ctrl+C发出了 SIGINT信号的时候,主进程不处理该信号,而子进程(线程)会进行默认处理,即退出。
  9. * 子进程退出的同时会向父进程(线程)发送SIGCHLD信号,表示子进程退出,由于该信号没有被阻塞,因此会导致
  10. * 主进程(线程)也立刻退出,出现了前述的运行情况。因而该问题的一个解决方法是在子线程生成前进行信号设置,
  11. * 或在子线程内部进行信号设置。
  12. *  Created on: Aug 14, 2011
  13. *      Author: xian0617
  14. */ 
  15.  
  16. #include <iostream> 
  17. #include "WaitQuitSignal.h" 
  18. sigset_t WaitQuitSignal::m_wait_mask; 
  19. struct timespec WaitQuitSignal::m_time; 
  20. //call this before thread create 
  21. void WaitQuitSignal::init(){ 
  22. try
  23.   signal(SIGKILL, SIG_IGN); 
  24.   sigemptyset(&m_wait_mask); 
  25.   sigaddset(&m_wait_mask, SIGINT); 
  26.   sigaddset(&m_wait_mask, SIGQUIT); 
  27.   sigaddset(&m_wait_mask, SIGTERM); 
  28.   pthread_sigmask(SIG_BLOCK, &m_wait_mask, 0); 
  29. } catch (std::exception& e){ 
  30.   std::cerr << "exception: " << e.what() << std::endl; 
  31. m_time.tv_sec=0; 
  32. m_time.tv_nsec =0; 
  33. bool WaitQuitSignal::wait(bool &flag){ 
  34. try
  35.   siginfo_t sig ; 
  36.   switch(sigtimedwait(&m_wait_mask,&sig,&m_time)){ 
  37.   case SIGINT: 
  38.   case SIGQUIT: 
  39.   case SIGTERM: 
  40.    flag=false
  41.    break
  42.   default
  43.    break
  44.   } 
  45.  
  46. } catch (std::exception& e){ 
  47.   std::cerr << "exception: " << e.what() << std::endl; 
  48. return flag; 


示例模型

  1. int main(int argc ,char **argv){ 
  2.     //step1 init 
  3.     WaitQuitSignal::init(); 
  4.     //step2 create subthread 
  5.      
  6.     //step3 wait signal 
  7.     while(WaitQuitSignal::wait(flag)){ 
  8.         sleep(1); 
  9.     } 
  10.     //step4 deal quit job 
  11.     //save(); 


  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值