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  
  12. #include  
  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_ */ 
/* * WaitQuitSignal.h * * Created on: Aug 14, 2011 * Author: xian0617 */ #ifndef WAITQUITSIGNAL_H_ #define WAITQUITSIGNAL_H_ #include #include class WaitQuitSignal { public: static void init(); static bool wait(bool&flag); private: static sigset_t m_wait_mask; static struct timespec m_time; }; #endif /* WAITQUITSIGNAL_H_ */


[cpp] view plain copy print ?
  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  
  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; 
/* * WaitQuitSignal.cpp * * Linux下的线程实质上是轻量级进程(light weighted process),线程生成时会生成对应的进程控制结构, * 只是该结构与父线程的进程控制结构共享了同一个进程内存空间。 同时新线程的进程控制结构将从父线程(进程) * 处复制得到同样的进程信息,如打开文件列表和信号阻塞掩码等。由于我们是在子线程生成之后修改了信号阻塞掩 * 码,此刻子线程使用的是主线程原有的进程信息,因此子线程仍然会对SIGINT和SIGTERM信号进行反应,因此当 * 我们用Ctrl+C发出了 SIGINT信号的时候,主进程不处理该信号,而子进程(线程)会进行默认处理,即退出。 * 子进程退出的同时会向父进程(线程)发送SIGCHLD信号,表示子进程退出,由于该信号没有被阻塞,因此会导致 * 主进程(线程)也立刻退出,出现了前述的运行情况。因而该问题的一个解决方法是在子线程生成前进行信号设置, * 或在子线程内部进行信号设置。 * Created on: Aug 14, 2011 * Author: xian0617 */ #include #include "WaitQuitSignal.h" sigset_t WaitQuitSignal::m_wait_mask; struct timespec WaitQuitSignal::m_time; //call this before thread create void WaitQuitSignal::init(){ try{ signal(SIGKILL, SIG_IGN); sigemptyset(&m_wait_mask); sigaddset(&m_wait_mask, SIGINT); sigaddset(&m_wait_mask, SIGQUIT); sigaddset(&m_wait_mask, SIGTERM); pthread_sigmask(SIG_BLOCK, &m_wait_mask, 0); } catch (std::exception& e){ std::cerr << "exception: " << e.what() << std::endl; } m_time.tv_sec=0; m_time.tv_nsec =0; } bool WaitQuitSignal::wait(bool &flag){ try{ siginfo_t sig ; switch(sigtimedwait(&m_wait_mask,&sig,&m_time)){ case SIGINT: case SIGQUIT: case SIGTERM: flag=false; break; default: break; } } catch (std::exception& e){ std::cerr << "exception: " << e.what() << std::endl; } return flag; }


示例模型

[cpp] view plain copy print ?
  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(); 
int main(int argc ,char **argv){ //step1 init WaitQuitSignal::init(); //step2 create subthread //step3 wait signal while(WaitQuitSignal::wait(flag)){ sleep(1); } //step4 deal quit job //save(); }


你可能感兴趣的:(linux网络编程)