pthread线程和信号
所有的异步信号发到整个进程的所有线程(异步信号如kill, lwp_kill, sigsend, kill等调用产生的都是,异步信号也称为中断),而且所有线程共享信号的处理行为(即sigaction的设置,对于同一信号的设置,某一线程的更改会影响到所有线程)。但每个线程可以有自己的mask来阻止信号的发送,所以可以通过线程对mask的设置来决定信号发送到哪个线程。设置mask的函数为:
#include
int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset)
此外,线程可以通过sleep(超过指定时间或调用的进程/线程捕捉到某个信号并从信号处理程序返回时,sleep返回)或者sigwait来等待一个或多个信号发生。
#include
int pthread_sigwait(const sigset_t *restrict set, int *restrict signop);
给进程发送信号可以调用kill,同样给线程调用信号可以使用pthread_kill
#include
int pthread_kill(pthread_t thread, int signo);
可以发送一个0的signo来检查线程是否存在,如果信号的默认行为是终止进程(例如SIGARLM),那么把该信号发送给某个线程会杀掉整个进程的所有线程。
另外注意ALARM是进程资源,并且所有线程共享相同的ALARM,设置一个alarm()会发送SIGARLM信号给所有线程,所以他们不可能互补干扰的使用alarm()。
here comes an example:
- /*threadsig.c*/
- #include
- #include
- #include
- void sighandler(int signo);
- void *
- thr1_fn(void *arg)
- {
- pthread_t tid = pthread_self();
- int rc;
- printf("thread 1 with tid:%u\n", tid);
- rc = sleep(60);
- if (rc != 0)
- printf("thread 1... interrupted at %d second\n", 60 - rc);
- printf("thread 1 ends\n");
- return NULL;
- }
- void *
- thr2_fn(void *arg)
- {
- struct sigaction action;
- pthread_t tid = pthread_self();
- int rc, err;
- printf("thread 2 with tid:%u\n", tid);
- action.sa_flags = 0;
- action.sa_handler = sighandler;
- err = sigaction(SIGALRM, &action, NULL);
- rc = sleep(60);
- if (rc != 0)
- printf("thread 2... interrupted at %d second\n", 60 - rc);
- printf("thread 2 ends\n");
- return NULL;
- }
- void *
- thr3_fn(void *arg)
- {
- pthread_t tid = pthread_self();
- sigset_t mask;
- int rc, err;
- printf("thread 3 with tid%u\n", tid);
- sigemptyset(&mask); /* 初始化mask信号集 */
- sigaddset(&mask, SIGALRM);
- err = pthread_sigmask(SIG_BLOCK, &mask, NULL);
- if (err != 0)
- {
- printf("%d, %s/n", rc, strerror(rc));
- return NULL;
- }
- rc = sleep(60);
- if (rc != 0)
- printf("thread 3... interrupted at %d second\n", 60 - rc);
- printf("thread 3 ends\n");
- return NULL;
- return NULL;
- }
- int
- main(void)
- {
- int rc, err;
- pthread_t thr1, thr2, thr3, thrm = pthread_self();
- printf("thread main with pid %u\n", (unsigned int)thrm);
- err = pthread_create(&thr1, NULL, thr1_fn, NULL);
- if (err != 0) {
- printf("error in creating pthread:%d\t%s\n",err, strerror(rc));
- exit(1);
- }
- /* pthread_kill(thr1, SIGALRM); send a SIGARLM signal to thr1 before thr2 set the signal handler, then the whole process will be terminated*/
- err = pthread_create(&thr2, NULL, thr2_fn, NULL);
- if (err != 0) {
- printf("error in creating pthread:%d\t%s\n",err, strerror(rc));
- exit(1);
- }
- err = pthread_create(&thr3, NULL, thr3_fn, NULL);
- if (err != 0) {
- printf("error in creating pthread:%d\t%s\n",err, strerror(rc));
- exit(1);
- }
- sleep(3);
- pthread_kill(thr1, SIGALRM);
- pthread_kill(thr2, SIGALRM);
- pthread_kill(thr3, SIGALRM);
- pthread_join(thr1, NULL); /*wait for the threads to complete.*/
- pthread_join(thr2, NULL);
- pthread_join(thr3, NULL);
- printf("main ends\n");
- return 0;
- }
- void
- sighandler(int signo)
- {
- pthread_t tid = pthread_self();
- printf("thread with pid:%u receive signo:%d\n", tid, signo);
- return;
- }
luffy@luffy-laptop:~/workspace/myapue$ ./threadsig
thread main with pid 3557979936
thread 1 with tid:3549923072
thread 2 with tid:3541530368
thread 3 with tid3533137664
thread with pid:3549923072 receive signo:14
thread with pid:3541530368 receive signo:14
thread 2... interrupted at 3 second
thread 1... interrupted at 3 second
thread 1 ends
thread 2 ends
#then wait for 27 seconds and thread-3 ends
thread 3 ends
main ends
thr2设置的信号处理程序
sighandler也应用到其他线程,thr3由于设置mask所有阻塞了SIGARLM信号。
Reference:
APUE
线程信号 http://blog.csdn.net/copal/article/details/5454279