- 来自: http://blog.csdn.net/xian0617/article/details/6689357
- /*
- * WaitQuitSignal.h
- *
- * Created on: Aug 14, 2011
- * Author: xian0617
- */
- #ifndef WAITQUITSIGNAL_H_
- #define WAITQUITSIGNAL_H_
- #include <signal.h>
- #include <time.h>
- 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_ */
- /*
- * WaitQuitSignal.cpp
- *
- * Linux下的线程实质上是轻量级进程(light weighted process),线程生成时会生成对应的进程控制结构,
- * 只是该结构与父线程的进程控制结构共享了同一个进程内存空间。 同时新线程的进程控制结构将从父线程(进程)
- * 处复制得到同样的进程信息,如打开文件列表和信号阻塞掩码等。由于我们是在子线程生成之后修改了信号阻塞掩
- * 码,此刻子线程使用的是主线程原有的进程信息,因此子线程仍然会对SIGINT和SIGTERM信号进行反应,因此当
- * 我们用Ctrl+C发出了 SIGINT信号的时候,主进程不处理该信号,而子进程(线程)会进行默认处理,即退出。
- * 子进程退出的同时会向父进程(线程)发送SIGCHLD信号,表示子进程退出,由于该信号没有被阻塞,因此会导致
- * 主进程(线程)也立刻退出,出现了前述的运行情况。因而该问题的一个解决方法是在子线程生成前进行信号设置,
- * 或在子线程内部进行信号设置。
- * Created on: Aug 14, 2011
- * Author: xian0617
- */
- #include <iostream>
- #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;
- }
示例模型
- 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();
- }