Linux _ pthread 线程 信号
线程的信号
线程的信号与进程之间的关系
线程没有自己独立的信号机制。
线程的信号依赖与所在的进程。
线程有自己的“信号屏蔽集合”,使得:
1)各线程可以向其同进程内的线程发送信号。(使用pthread_kill
2)各线程可以设置几的“信号屏蔽集合”,其初值从创建线程中继承。
信号屏蔽集合类似与进程的信号屏蔽字,
但它只作用于该线程。
使用pthread_sigmask(类似于进程的sigprocmask函数)
3)各线程共享对某信号的处理方法,
即收到信号后,各线程执行相同的处理函数。
除非该信号被该线程屏蔽。注意:进程收到能够“终止”该进程的信号后,该进程里的所有线程都将终止。
向线程发送信号
pthread_kill
原型:int pthread_kill (pthread_t thread, int sig);
参数:sig, 如果为0,则检测对应的线程thread是否存在设置线程的信号屏蔽集合
pthread_sigmask
原型: int pthread_sigmask(int how,
const sigset_t *restrict set,
sigset_t *restrict oset);
注意:用法和sigprocmask相似。注意:SIGKILL和SIGSTOP,对进程和线程都不能屏蔽。
- 实例
主线程中,分别创建两个线程
在线程1中,屏蔽SIGUSR2之外的所有信号。即仅对其开放SIGUSR2
设置SIGUSR1的信号处理函数
在线程2中,设置SIGUSR2的信号处理函数
在主线程中,分别向线程1发送SIGUSR1、SIGUSR2信号
分别向线程2发送SIGUSR1、SIGUSR2信号
最后,向线程1发送SIGKILL信号。
main5.c
- 实例
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void sigusr_handle (int arg)
{
printf("thread(id=%u) catch signal %d\n", pthread_self(), arg);
}
void * th1_handle(void *arg)
{
int i;
sigset_t set;
sigfillset(&set);
sigdelset(&set, SIGUSR2);
pthread_sigmask(SIG_SETMASK, &set, 0);
signal(SIGUSR1, sigusr_handle);
for (i=0; i<5; i++) {
printf("this is in thread 1(id=%u)\n", pthread_self());
pause();
}
}
void * th2_handle(void *arg)
{
int i;
signal(SIGUSR2, sigusr_handle);
for (i=0; i<5; i++) {
printf("this is in thread 2(id=%u)\n", pthread_self());
pause();
}
}
int main(void)
{
pthread_t mythread1, mythread2;
int ret;
ret = pthread_create(&mythread1, NULL, th1_handle, NULL);
if (ret != 0) {
printf("create thread failed!\n");
}
ret = pthread_create(&mythread2, NULL, th2_handle, NULL);
if (ret != 0) {
printf("create thread failed!\n");
}
sleep(3);
ret = pthread_kill(mythread1, SIGUSR1);
if (ret != 0) {
printf("pthread_kill SIGUSR1 failed!\n");
exit(1);
}
ret = pthread_kill(mythread1, SIGUSR2);
if (ret != 0) {
printf("pthread_kill SIGUSR2 failed!\n");
exit(1);
}
ret = pthread_kill(mythread2, SIGUSR1);
if (ret != 0) {
printf("pthread_kill SIGUSR1 failed!\n");
exit(1);
}
sleep(1);
ret = pthread_kill(mythread2, SIGUSR2);
if (ret != 0) {
printf("pthread_kill SIGUSR2 failed!\n");
exit(1);
}
ret = pthread_kill(mythread1, SIGKILL);
if (ret != 0) {
printf("pthread_kill SIGKILL failed!\n");
exit(1);
}
pthread_join(mythread1, NULL);
pthread_join(mythread2, NULL);
printf("main thread end!\n");
return 0;
}