线程和信号

每个线程都有自己的信号屏蔽字,但信号在进程中,是对所有线程共享的.
问题:
若单个线程修改了信号的处理方式,所有线程都会使用这个被修改的信号处理方式.
每个线程均有自己的信号屏蔽集(信号掩码),可以使用pthread_sigmask函数来
屏蔽某个线程对某些信号的响应处理.
解决:
每个线程都有自己的屏蔽字, 调用pthread_sigmask 来屏蔽信号处理.

 kill : 用在进程间,进程中的所有线程都会接收处理,处理有线程屏蔽字.
 pthread_kill :用在线程间.
 子线程会继承主线程信号, 可以通过pthread_sigmask来屏蔽.

 **关键接口:**
    pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
          屏蔽指定信号,配合接口sigaddset
          屏蔽所有信号,....sigfillset(&mask);
          不屏蔽任何信号,..sigemptyset(&mask);
          (这里的屏蔽本人理解就是阻塞)
   sigdelset(&set, SIGALRM);
        将参数signum代表的信号从参数set信号集里删除。
   sigwait(&set, &sig);
        只是从未决队列中删除该信号,并不改变信号掩码。也就是,当sigwait函数返回,它监听的信号依旧被阻塞。  
 参考:
      http://www.leoox.com/?p=321
      http://blog.csdn.net/yusiguyuan/article/details/14230719
            #include<stdio.h>
            #include<pthread.h>
            #include<signal.h>

            static void sig_alrm(int signo);
            static void sig_init(int signo);
            int main()
            {
                sigset_t set;
                int sig;
                sigemptyset(&set);
                sigaddset(&set, SIGALRM);
                pthread_sigmask(SIG_SETMASK, &set, NULL);//阻塞SIGALRM信号

                signal(SIGALRM, sig_alrm);
                signal(SIGINT, sig_init);
                sigwait(&set, &sig);//sigwait只是从未决队列中删除该信号,并不改变信号掩码。也就是,当sigwait函数返回,它监听的信号依旧被阻塞。
                switch(sig)
                {
                   case 14:
                       printf("sigwait, receive signal SIGALRM\n"); /*do the job when catch the sigwait*/           
                       break;
                   default:
                        break;
                }
                sigdelset(&set, SIGALRM); //删除信号集中的屏蔽字. 这样pthread_sigmask接口就不会屏蔽了,就可以调用信号处理.
                pthread_sigmask(SIG_SETMASK, &set, NULL);

                for(;;){  }
                return 0;
            }

            static void sig_alrm(int signo)
            {
                printf("after sigwait, catch SIGALRM\n");
                fflush(stdout);
                return ;
            }

            static void sig_init(int signo)
            {
                printf("catch SIGINT\n");
                return ;
            }    
     执行:
        第一次发送kill -14 17457(进程号)时打印switch里面的语句:
        sigwait, receive signal SIGALRM
        之后发送SIGALRM信号的话将被信号处理程序捕捉。
        after sigwait, catch SIGALRM
        after sigwait, catch SIGALRM
        after sigwait, catch SIGALRM
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值