当前位置: 技术问答>linux和unix
有关linux信号问题
来源: 互联网 发布时间:2016-10-25
本文导语: #include..... ............. sigset_t oldmask,mask; void func(int); void *thr_func(void *arg) { pthread_sigmask(SIG_BLOCK,&mask,&oldmask); signal(SIGINT,func); } void func(int signo) { pintf("SIGINT recieved\n");...
#include.....
.............
sigset_t oldmask,mask;
void func(int);
void *thr_func(void *arg)
{
pthread_sigmask(SIG_BLOCK,&mask,&oldmask);
signal(SIGINT,func);
}
void func(int signo)
{
pintf("SIGINT recieved\n");
}
int main(void)
{
pthread_t tid;
sigemptyset(&mask);
sigaddset(&mask,SIGINT);
pthread_create(&tid,NULL,thr_func,NULL);
sleep(20);
exit(0);
}
疑问:1为什么按ctrl-c中断信号(时线程还能收到,并执行信号处理,不是已经被 pthread_sigmask(SIG_BLOCK,&mask,&oldmask);阻塞了吗?
.............
sigset_t oldmask,mask;
void func(int);
void *thr_func(void *arg)
{
pthread_sigmask(SIG_BLOCK,&mask,&oldmask);
signal(SIGINT,func);
}
void func(int signo)
{
pintf("SIGINT recieved\n");
}
int main(void)
{
pthread_t tid;
sigemptyset(&mask);
sigaddset(&mask,SIGINT);
pthread_create(&tid,NULL,thr_func,NULL);
sleep(20);
exit(0);
}
疑问:1为什么按ctrl-c中断信号(时线程还能收到,并执行信号处理,不是已经被 pthread_sigmask(SIG_BLOCK,&mask,&oldmask);阻塞了吗?
|
补充说明
1. 默认情况下,信号将由主进程接收处理,就算信号处理函数是由子线程注册的
2. 每个线程均有自己的信号屏蔽字,可以使用sigprocmask函数来屏蔽某个线程对该信号的响应处理,
仅留下需要处理该信号的线程来处理指定的信号。
3. 对某个信号处理函数,以程序执行时最后一次注册的处理函数为准,即在所有的线程里,
同一个信号在任何线程里对该信号的处理一定相同
1. 默认情况下,信号将由主进程接收处理,就算信号处理函数是由子线程注册的
2. 每个线程均有自己的信号屏蔽字,可以使用sigprocmask函数来屏蔽某个线程对该信号的响应处理,
仅留下需要处理该信号的线程来处理指定的信号。
3. 对某个信号处理函数,以程序执行时最后一次注册的处理函数为准,即在所有的线程里,
同一个信号在任何线程里对该信号的处理一定相同
|
对于线程来说,信号屏蔽字是私有的,而信号处理程序时共享的。
产生的大部分信号会被任意递送到一个线程。
产生的大部分信号会被任意递送到一个线程。
|
默认情况下,信号派发给某个活动并且不阻塞信号的线程。LZ的这个工作线程的确是阻塞了,但是主线程没有。因此,派发给主线程。
线程修改自己的信号mask用pthread_sigmask()
多线程环境下,对信号的处理,与单线程环境下的处理,方式不同。建议的方式是,将所有需要处理的信号,集中在某“一”个线程处理,用sigwait(),做到单一处处理。而其他线程,都阻塞这些信号。由于信号只会派发给不阻塞的线程,因此,感觉上就象是堵住所有的路,只留下唯一的路让水流走。惯例上,会在主线程进行阻塞信号的工作,然后创建工作线程,工作线程在创建时,继承了主线程的屏蔽字。如此做到“堵住”。其中,某个工作线程调用sigwait()来等待特定的信号集合。
总的说,信号在多线程下编程,需要重新考虑,与以往的单线程程序不同。
|
我的确认为pthread_sigmask()在非主线程中,没有什么调用的必要。如果按照推荐的模式去写程序,处理信号的话。