首先看这篇文章学习线程和信号:http://www.cnblogs.com/clover-toeic/p/4126594.html
然后我写了一个小程序
#include <stdio.h> #include <pthread.h> #include <signal.h> /* 测试与线程有关的信号函数 */ sigset_t new_mask , old_mask; void *thread_func( void *arg ); int main(int argc , char *argv[]){ pthread_t thrd; pr_mask( " main begin: "); //set signal set sigemptyset( &new_mask ); sigaddset( &new_mask , SIGUSR1 ); sigaddset( &new_mask , SIGINT); /* Block SIGINT; other threads created by main() will inherit a copy of the signal mask. */ //first mask some signals if( pthread_sigmask( SIG_BLOCK , &new_mask , &old_mask) != 0 ) oops( "thread mask:"); //创建线程 if( pthread_create( &thrd , NULL , thread_func , NULL) != 0) oops( "thread create: "); //等待子线程结束 pthread_join( thrd , NULL ); pr_mask( " main exit: "); return 0; } void *thread_func( void *arg ){ int err ,signop; int count ; count = 0; pr_mask( " in thread: " ); while( count++ < 5 ){ err = sigwait( &new_mask ,&signop ); if( err != 0 ) oops( " sigwait: "); switch( signop ){ case SIGINT: printf( " catch sigint.\n "); break; case SIGUSR1: printf( "catch sigusr1.\n " ); break; default: printf( "unkown signal.\n"); break; } } //reset mask if( pthread_sigmask( SIG_SETMASK , &old_mask , NULL) != 0 ) oops( " thread mask :" ); pr_mask( " after set mask :"); }
#include <stdio.h> #include <errno.h> #include <signal.h> void pr_mask( const char *str ){ sigset_t set; int errno_save; //get the pre errno errno_save = errno; if( sigprocmask( 0, NULL , &set ) == -1 ) oops( " sigmask" ); else{ printf( "%s" , str ); if( sigismember( &set , SIGQUIT ) ) printf( " SIGQUIT" ); if( sigismember( &set , SIGINT ) ) printf( " SIGINT" ); if( sigismember( &set , SIGUSR1 ) ) printf( " SIGUSR1" ); if( sigismember( &set , SIGALRM ) ) printf( " SIGALRM" ); printf("\n"); } errno = errno_save ; }
#include <stdio.h> #include <stdlib.h> void oops(void *msg){ perror(msg); exit(1); }
在linux系统上默认情况下,信号将由主进程接收处理,就算信号处理函数是由子线程注册的, 在Linux中的posix线程模型中,线程拥有独立的进程号,可以通过getpid()得到线程的进程号,而线程号保存在pthread_t的值中。而主线程的进程号就是整个进程的进程号,因此向主进程发送信号只会将信号发送到主线程中去。如果主线程设置了信号屏蔽,则信号会投递到一个可以处理的线程中去(这解释了man中的示例程序行为)。
其他可以参考:
http://bbs.chinaunix.net/thread-4088635-1-1.html
http://blog.csdn.net/yusiguyuan/article/details/14230719
http://blog.csdn.net/yusiguyuan/article/details/14237277