1. 程式人生 > >多執行緒中的訊號機制--sigwait()函式

多執行緒中的訊號機制--sigwait()函式

這個例子演示了:通過在主執行緒中阻塞一些訊號,其它的執行緒會繼承訊號掩碼,然後專門用一個執行緒使用sigwait函式來同步的處理訊號,使其它的執行緒不受到訊號的影響。

#include <pthread.h>
#include <stdio.h>
#include <sys/signal.h>
#define NUMTHREADS 3
void sighand(int signo);
void *threadfunc(void *parm)
{
	pthread_t             tid = pthread_self();
	int                   rc;
	printf("Thread %u entered\n", tid);
	rc = sleep(3);
	printf("Thread %u did not get expected results! rc=%d\n", tid, rc);
	return NULL;
}
void *threadmasked(void *parm)
{
	pthread_t             tid = pthread_self();
	sigset_t              mask;
	int                   rc;
	printf("Masked thread %lu entered\n", tid);
	sigfillset(&mask); /* Mask all allowed signals */
//	sigemptyset(&mask);
	rc = pthread_sigmask(SIG_BLOCK, &mask, NULL);
	if (rc != 0)
	{
		printf("%d, %s\n", rc, strerror(rc));
		return NULL;
	}
	rc = sleep(1);
	if (rc != 0)
	{
		printf("Masked thread %lu did not get expected results! ""rc=%d \n",tid, rc);
		return NULL;
	}
//	sigwait(&mask,&rc);
	printf("Masked thread %lu completed masked work\n",tid);
	return NULL;
}
int main(int argc, char **argv)
{
	int                     rc;
	int                     i;
	struct sigaction        actions;
	pthread_t               threads[NUMTHREADS];
	pthread_t               maskedthreads[NUMTHREADS];
	printf("Enter Testcase - %s\n", argv[0]);
	printf("Set up the alarm handler for the process\n");
	memset(&actions, 0, sizeof(actions));
	sigemptyset(&actions.sa_mask);
	actions.sa_flags = 0;
	actions.sa_handler = sighand;
	rc = sigaction(SIGALRM,&actions,NULL);
	printf("Create masked and unmasked threads\n");
	for(i=0; i<NUMTHREADS; ++i)
	{
		rc = pthread_create(&threads[i], NULL, threadfunc, NULL);
		if (rc != 0)
		{
			printf("%d, %s\n", rc, strerror(rc));
			return -1;
		}
		rc = pthread_create(&maskedthreads[i], NULL, threadmasked, NULL);
		if (rc != 0)
		{
			printf("%d, %s\n", rc, strerror(rc));
			return -1;
		}
	}
	sleep(5);
	printf("Send a signal to masked and unmasked threads\n");
	for(i=0; i<NUMTHREADS; ++i)
	{
		rc = pthread_kill(threads[i], SIGALRM);
		rc = pthread_kill(maskedthreads[i], SIGALRM);
	}
	printf("Wait for masked and unmasked threads to complete\n");
	for(i=0; i<NUMTHREADS; ++i) {
		rc = pthread_join(threads[i], NULL);
		rc = pthread_join(maskedthreads[i], NULL);
	}
	printf("Main completed\n");
	return 0;
}
void sighand(int signo)
{
	pthread_t             tid = pthread_self();
	printf("Thread %lu in signal handler\n",tid);
	return;

}
(ps:由上面的幾篇文章可知,執行緒中的訊號處理機制和程序中的訊號處理機制是不同的,或者說是完全不同的,一般在多執行緒中使用訊號的,或單獨啟動一個執行緒類處理訊號,在主程序中傳送訊號,在主程序中使用了pthread_mask()函式來處理訊號遮蔽資訊,這個時候在主程序中使用kill,這個時候執行緒也是可以接受到訊號的原因是pthread_mask繼承了主程序的訊號遮蔽資訊,這個時候也是可以在使用pthread_kill給相應的執行緒傳送相應的訊號,但是在有的程式中,線上程中使用pthread_mask,這個使用就必須使用pthread_kill來發送訊號了;但是在程序中的訊號機制沒有這麼複雜,程序中只需要註冊一個函式,就靜靜的等待訊號處理。不過在程序中使用的方法也是可以線上程中使用的)