gpengtao的专栏

全世界有那么多的人在琢磨计算机,你能在什么地方比其他人都更进一步呢。...

线程与信号

总结:

signal()设置对某种信号的处理方式,只能有一种处理方式,即设置进程、线程的信号handler,对进程、线程都有效。
pthread_kill()可以向线程发送信号。
pthread_sigmask()设置线程的阻塞信号集,但是仅仅对该线程有效。
kill()向进程发送信号,由哪个线程处理该信号是未知的。可能发生的情况是,进程本身屏蔽了该信号,而某个线程没有屏蔽改信号,进而该线程处理了该信号。

示例:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>

void sig_thread_func(int sig)
{
	printf("sig_thread_func : sig = %d\n", sig);
}
void sig_func(int sig)
{
	printf("sig_func : sig = %d\n",sig);
}

void *func1(void *arg)
{
    signal(SIGUSR1, sig_thread_func);   //线程1先运行,设置了signal

	sigset_t set;
	sigfillset(&set);
	sigdelset(&set, SIGUSR1);
	pthread_sigmask(SIG_SETMASK, &set, NULL);//线程1屏蔽了除了SIGUSR1外的所有信号

	printf("pthread 1 run\n");
	int i;
	for(i = 0; i < 7; ++i)
	{
		printf("1...\n");
		sleep(1);
	}
	return 0;
}
void *func2(void *arg)
{
	printf("pthread 2 run\n");
	int i;
	for(i = 0; i < 7; ++i)
	{
		printf("2...\n");
		sleep(1);
	}
	return 0;
}

int main()
{
	pthread_t tid1, tid2;
	pthread_create(&tid1, NULL, func1, NULL);
	pthread_create(&tid2, NULL, func2, NULL);

	sleep(1);
	signal(SIGUSR1, sig_func);  //覆盖了线程1设置的signal

    //向线程1发送SIGUSR1,SIGUSR2
	sleep(1);
	pthread_kill(tid1, SIGUSR1);//调动handler
	sleep(1);
	pthread_kill(tid1, SIGUSR2);//屏蔽了,无响应

    //向线程2发送SIGUSR1,SIGUSR2
	sleep(1);
	pthread_kill(tid2, SIGUSR1);//调用handler
	sleep(1);
	//pthread_kill(tid2, SIGUSR2);//会终止进程,是进程!

	sigset_t set;
	sigfillset(&set);
	sigprocmask(SIG_SETMASK, &set, NULL);//进程屏蔽了所有信号

	sleep(1);
	kill(getpid(), SIGUSR1);//调动handler?其实是线程1响应的

	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);

	return 0;
}
结果:

pthread 1 run
1...
pthread 2 run
2...
1...
2...
sig_func : sig = 10
1...
2...
1...
2...
sig_func : sig = 10
2...
1...
2...
1...
2...
sig_func : sig = 10
1...

一共对SIGUSR1响应了3次,分别是线程1、2、1响应的。





阅读更多
个人分类: Linux & Unix
上一篇linux守护进程 编写要点
下一篇ioctl()函数获取本机IP、MAC
想对作者说点什么? 我来说一句

线程信号

qq_20218109 qq_20218109

2016-08-02 21:25:24

阅读数:67

没有更多推荐了,返回首页

关闭
关闭