作者:冬天的芦苇2011 | 来源:互联网 | 2023-09-23 17:18
一、发送信号的函数 int pthread_kill(pthread_t thread, int sig);
1、别被名字吓到,pthread_kill可不是kill,而是向线程发送signal。还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用sigaction()去抓信号并加上处理函数。
2、向指定ID的线程发送sig信号,如果线程代码内不做处理,则按照信号默认的行为影响整个进程,也就是说,如果你给一个线程发送了SIGQUIT,但线程却没有实现signal处理函数,则整个进程退出。如果要获得正确的行为,就需要在线程内实现sigaction了。所以,如果int sig的参数不是0,那一定要清楚到底要干什么,而且一定要实现线程的信号处理函数,否则,就会影响整个进程。如果int sig是0呢,这是一个保留信号,其实并没有发送信号,作用是用来判断线程是不是还活着。
二、信号处理 1、进程信号处理: int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
给信号signum设置一个处理函数,处理函数在sigaction中指定 act.sa_mask 信号屏蔽字 act.sa_handler 信号集处理程序
2、信号集的处理
int sigemptyset ( sigset_t * set) ; int sigfillset ( sigset_t * set) ; int sigaddset ( sigset_t * set, int signum) ; int sigdelset ( sigset_t * set, int signum) ;
3、多线程信号屏蔽处理 /* int sigprocmask(int how, const sigset_t *set, sigset_t oldset) /这是进程的信号屏蔽处理
int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);
how = SIG_BLOCK:向当前的信号掩码中添加set,其中set表示要阻塞的信号组。 SIG_UNBLOCK:向当前的信号掩码中删除set,其中set表示要取消阻塞的信号组。 SIG_SETMASK:将当前的信号掩码替换为set,其中set表示新的信号掩码。 在多线程中,新线程的当前信号掩码会继承创造它的线程的信号掩码。 一般情况下,被阻塞的信号将不能中断此线程的执行,除非此信号的产生是因为程序运行出错如 SIGSEGV;另外不能被忽略处理的信号 SIGKILL 和 SIGSTOP 也无法被阻塞。
三、实例 #include #include #include #include #include #include #include "include/pthread.h" #ifndef _WIN64 #pragma comment(lib,".\\lib32\\pthreadVC2.lib") #pragma comment(lib,".\\lib32\\pthreadVCE2.lib") #pragma comment(lib,".\\lib32\\pthreadVSE2.lib") #else #pragma comment(lib,".\\lib64\\pthreadVC2.lib") #endif void sig_handler1 ( int arg) { printf ( "thread1 get signal\n" ) ; return ; } void sig_handler2 ( int arg) { printf ( "thread2 get signal\n" ) ; return ; } void * thread_fun1 ( void * arg) { printf ( "new thread 1\n" ) ; struct sigaction act; memset ( & act, 0 , sizeof ( act) ) ; sigaddset ( & act. sa_mask, SIGQUIT) ; act. sa_handler = sig_handler1; sigaction ( SIGQUIT, & act, NULL ) ; pthread_sigmask ( SIG_BLOCK, & act. sa_mask, NULL ) ; Sleep ( 2 ) ; return ( void * ) 0 ; } void * thread_fun2 ( void * arg) { printf ( "new thread 2\n" ) ; struct sigaction act; memset ( & act, 0 , sizeof ( act) ) ; sigaddset ( & act. sa_mask, SIGQUIT) ; act. sa_handler = sig_handler2; sigaction ( SIGQUIT, & act, NULL ) ; Sleep ( 2 ) ; } int main ( ) { pthread_t tid1, tid2; int err; int s; err = pthread_create ( & tid1, NULL , thread_fun1, NULL ) ; if ( err!= 0 ) { printf ( "create new thread 1 failed\n" ) ; return 0 ; } err = pthread_create ( & tid2, NULL , thread_fun2, NULL ) ; if ( err != 0 ) { printf ( "create new thread 2 failed\n" ) ; return 0 ; } Sleep ( 1 ) ; s = pthread_kill ( tid1, SIGQUIT) ; if ( s!= 0 ) { printf ( "send signal to thread1 failed\n" ) ; } s = pthread_kill ( tid2, SIGQUIT) ; if ( s != 0 ) { printf ( "send signal to thread2 failed\n" ) ; } pthread_join ( tid1, NULL ) ; pthread_join ( tid2, NULL ) ; return 0 ; }