Linux中线程与信号

     由于进程中所有线程共享该进程信号,所以线程库将根据线程掩码决定把信号发送给哪个具体的线程。因此在每个子线程中都单独设置信号掩码,就很容易导致逻辑错误。此外,所有线程共享信号处理函数。也就是说,一个线程中设置了某个信号的信号处理函数后,它将覆盖其他线程为同一个信号设置的信号处理函数。所以应该定义一个专门的线程来处理所有的信号。

(1)在主线程创建出其他子线程之前调用pthread_sigmask来设置好信号掩码,所有新创建的子线程都将自动继承这个信号掩码。这样做之后,实际上所有线程都不会响应被屏蔽的信号了。

(2)在某个线程中调用如下函数来等待信号并处理之:

#include<signal.h>

int sigwait(const sigset_t * set,int *sig);

set参数指定需要等待的信号的集合。参数sig指定的整数用于存储该函数返回的信号值。成功时返回0,失败则返回错误码。

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

/* Simple error handling functions */

#define handle_error_en(en, msg) \
               do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

static void *sig_thread(void *arg)
{
	printf("yyyyy, thread id is: %ld\n", pthread_self());
	sigset_t aset;
	int s, sig;
	sigemptyset(&aset);
	sigaddset(&aset, SIGQUIT);
	sigaddset(&aset, SIGUSR1);
	//s = pthread_sigmask(SIG_BLOCK, &aset, NULL);
	sigset_t *set = (sigset_t *) arg;

	for (;;) {
		s = sigwait(set, &sig);
		if (s != 0)
			handle_error_en(s, "sigwait");
		printf("Signal handling thread got signal %d\n", sig);
	}
}

static void handler(int arg)
{
	printf("xxxxx, thread id is: %ld\n", pthread_self());
}

int main(int argc, char *argv[])
{
	pthread_t thread;
	sigset_t set;
	int s;

	/* Block SIGINT; other threads created by main() will inherit
	 *               a copy of the signal mask. */

	signal(SIGQUIT, handler);
	//           if (s != 0)
	//             handle_error_en(s, "pthread_sigmask");

	s = pthread_create(&thread, NULL, &sig_thread, (void *) &set);
	sigemptyset(&set);
	sigaddset(&set, SIGQUIT);
	sigaddset(&set, SIGUSR1);
	//s = pthread_sigmask(SIG_BLOCK, &set, NULL);
	if (s != 0)
		handle_error_en(s, "pthread_create");
	printf("sub thread with id: %ld\n", thread);
	/* Main thread carries on to create other threads and/or do
	 *               other work */

	pause(); /* Dummy pause so we can test program */
}



你可能感兴趣的:(Linux中线程与信号)