linux多线程信号的记录

引言:
本文理论部分来源于此博客:https://www.cnblogs.com/cobbliu/p/5592659.html
代码部分来源于曹老师的文章:
https://blog.csdn.net/rheostat/article/details/8563987?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158769880419724848336974%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=158769880419724848336974&biz_id=0&utm_source=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-2
 
正文:
1、 Linux 多线程应用中,每个线程可以通过调用pthread_sigmask() 设置本线程的信号掩码。
    一般情况下,被阻塞的信号将不能中断此线程的执行,除非此信号的产生是因为程序运行出错如SIGSEGV;
    //所以这里的理解是,设置信号后,便让进程拥有了中断处理能力,一旦接收到信号,便选取一个线程打断其工作,
    //让其处理此信号,也就是调用该信号处理函数。
   
2、默认情况下,信号将由主进程接收处理,就算信号处理函数是由子线程注册的。
3、发送信号给进程,哪个线程会收到?
        APUE说,在多线程的程序中,如果不做特殊的信号阻塞处理,当发送信号给进程时,
        由系统选择一个线程来处理这个信号。
       
4、如果进程中,有的线程可以屏蔽了某个信号,而某些线程可以处理这个信号,
        则当我们发送这个信号给进程或者进程中不能处理这个信号的线程时,系统会将这个信号投递到进程号最小
        的那个可以处理这个信号的线程中去处理。
5、当一个线程调用pthread_create() 创建新的线程时,此线程的信号掩码会被新创建的线程继承。
            问题是,如果创建子线程在设置本线程的信号掩码前,它还会继承吗?
                    答:不会。修改文章尾代码,将信号集的设置放在创建子线程前,运行结果如下:
 

        代码就不重复粘贴。放个截图,其余不变动

            第二个问题,如果所有的线程都屏蔽了这个信号,这个信号由谁来执行。
                    答:接上个问题,把信号掩码的设置放在创建子线程前,也就是子线程继承主线程的屏蔽掩码,
                        那么所有的线程均屏蔽掩码后,信号处理函数无人执行!由上图可见。
           
5、每个线程均有自己的信号屏蔽字,可以使用sigprocmask函数来屏蔽某个线程对该信号的响应处理,
   仅留下需要处理该信号的线程来处理指定的信号。
  
6、对某个信号处理函数,以程序执行时最后一次注册的处理函数为准,即在所有的线程里,
   同一个信号在任何线程里对该信号的处理一定相同
  
7、sleep和nanosleep,如果没有在它调用之前设置信号屏蔽字的话,都可能会被信号处理函数打断。
   //第7点很重要
  
8、实例:
        #include <stdio.h>
        #include <pthread.h>
        #include <stdlib.h>
        #include <signal.h>
        #include <unistd.h>
        void sig_handler(int signo)
        {
          alarm(2);
          printf("alarm signal/n");
        }
        void *pthread_func()
        {
                  alarm(2);
                  while(1)
                  {
                           pause();
                  }
        }
        int main(int argc, char **argv)
        {
                  pthread_t tid, tid_1;
                  int retval;
        
                  signal(SIGALRM, sig_handler);
                  if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
                  {
                           perror("pthread_create");
                           exit(-1);
                  }

                  sigset_t sigset;
                  sigemptyset(&sigset);
                  sigaddset(&sigset, SIGALRM);
                  pthread_sigmask(SIG_SETMASK,&sigset,NULL);
                  while(1)
                  {
                           printf("main pthread/n");
                           sleep(10);
                  }
                  return 0;
        }

猜你喜欢

转载自www.cnblogs.com/menglang-/p/12766559.html