linux信号机制

1.signal 是比较传统的linux函数,存在缺陷,表现在信号不可靠(丢失...), 绝对不要使用(linux保留该函数只是为了兼容)

eg: 通常使用signal(SIGPIPE, SIG_IGN)用以忽略 sigpipe,但是在多线程中只在主线程设置却是不够的,一种解决方法是在每个线程都设置,

根本原因在于如果一个sigpipe正在处理的话,新来的sigpipe信号会采用默认处理方式处理(而默认的处理方式就是让进程退出);

真正避免sigpipe的正确方法是:

方法一:

   sigset_t signal_mask;
   sigemptyset (&signal_mask);
   sigaddset (&signal_mask, SIGPIPE);
   int rc = pthread_sigmask (SIG_BLOCK, &signal_mask, NULL);
   if (rc != 0)
   {
      printf("block sigpipe error\n");
   } 

方法二:

使用sigaction函数

    void sigcatcher(int sig, int /*sinfo*/, struct sigcontext* /*sctxt*/)

   {

   }

    struct sigaction act;
    
    sigemptyset(&act.sa_mask);  //清空,初始化
    act.sa_flags = 0;
    act.sa_handler = (void(*)(int))&sigcatcher;    //也可用SIG_IGN

     (void)::sigaction(SIGPIPE, &act, NULL);


2.信号处理函数需要注意不能包含不可重入的函数,如果与程序中其它函数冲突会造成不可预料的后果(相当于不可重入函数在多线程中)

3.sigprocmask可以用来屏蔽信号

eg: ppoll中相当于对poll使用如下用法:

           sigset_t origmask;
           int timeout;

           timeout = (timeout_ts == NULL) ? -1 :  (timeout_ts.tv_sec * 1000 + timeout_ts.tv_nsec / 1000000);
           sigprocmask(SIG_SETMASK, &sigmask, &origmask);     //设置信号屏蔽
           ready = poll(&fds, nfds, timeout);
           sigprocmask(SIG_SETMASK, &origmask, NULL); //恢复

参考书目:
          UNIX高级环境编程


你可能感兴趣的:(C,C++)