1. 程式人生 > >程序執行緒中睡眠函式(sleep)被訊號中斷後失效,處理方式總結

程序執行緒中睡眠函式(sleep)被訊號中斷後失效,處理方式總結

#include
#include
#include
#include

#include
#include

void tid1_handler(void *arg);
void tid1_SIGINT_fun(int signo);
void tid1_SIGQUIT_fun(int signo);
void tid2_handler(void *arg);
void tid2_SIGUSR2_fun(int signo);
pthread_t tid1 , tid2; //建立全域性的子執行緒標識
int main(void){
	
	//訊號處理,先遮蔽所有的訊號
	//定義一個訊號的集合
	sigset_t sig_sets;
	//置空訊號集合
	sigemptyset(&sig_sets);
	//裝填所有的訊號
	sigfillset(&sig_sets);
	//開始遮蔽
	//sigprocmask(SIG_BLOCK , &sig_sets , NULL);
	pthread_sigmask(SIG_BLOCK , &sig_sets , NULL);
	//---所有訊號遮蔽完成


	
	//建立兩個子執行緒並設定處理函式
	pthread_create(&tid1 , NULL , (void *)tid1_handler , NULL);
	pthread_create(&tid2 , NULL , (void *)tid2_handler , NULL);
	
	//while(1);
	pthread_join(tid1 , NULL);
	pthread_join(tid2 , NULL);

	printf("主執行緒開始退出啦 ....\n");

	return 0;
}

void tid1_handler(void *arg){
	//pthread_detach(tid1);
	//子執行緒1處理函式  且對 SIGINT 訊號開放
	//定義一個訊號的集合
	sigset_t set1;
	//置空訊號集合
	sigemptyset(&set1);
	//裝填訊號
	sigaddset(&set1 , SIGINT);
	sigaddset(&set1 , SIGQUIT);
	//安裝訊號
	signal(SIGINT , tid1_SIGINT_fun);
	signal(SIGQUIT , tid1_SIGQUIT_fun);
	//放開遮蔽的訊號
	//int sig  = 0;
	//sigwait(&set1 , &sig);
	//printf("sig = %d \n",sig);
	pthread_sigmask(SIG_UNBLOCK , &set1 , NULL);
	//重新發送可能被遮蔽的訊號
	int ret = -1;
	ret = sigpending(&set1);
	if(ret < 0){
		perror("sigpending");
		exit(1);
	}
	int i = 0;
	while(1){
	
		printf("tid1 is running [%3d]\n" , i++);
		sleep(1);
	}


}

void tid1_SIGINT_fun(int signo){
	//訊號執行
	if(SIGINT == signo){
		printf("                     tid1 --->receive a SIGINT signal\n");
		pthread_kill(tid2 , SIGUSR2);
	}
}

void tid1_SIGQUIT_fun(int signo){
	//訊號執行
	if(SIGQUIT ==signo){
		printf("                     tid1 --->receive a SIGQUIT signal\n");
		exit(1);
	}

}

void tid2_handler(void *arg){

	//pthread_detach(tid2);

	//子執行緒2處理函式
	//定義一個訊號集合
	sigset_t set2;
	//置空訊號集合
	sigemptyset(&set2);
	//裝填訊號
	sigaddset(&set2 , SIGUSR2);
	//安裝訊號
	signal(SIGUSR2 , tid2_SIGUSR2_fun);
	//放開遮蔽的訊號
	pthread_sigmask(SIG_UNBLOCK , &set2 , NULL);
	//重新發送可能被遮蔽的訊號
	sigpending(&set2);
#if 1
	int i = 30;
	while(i--){
		sleep(1);
	}
#else
	sleep(30);
#endif
	pthread_exit(NULL);
	
}

void tid2_SIGUSR2_fun(int signo){

	//訊號執行
	if(SIGUSR2 == signo){
		printf("                     tid2 --->receive a SIGUSR2 signal \n");
	}
}