您的位置:首页 > 大数据 > 人工智能

线程控制-sigwait函数和相关函数解释

2016-05-12 09:06 591 查看
首先看这篇文章学习线程和信号: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);
}


然后执行:我发送 kill -SIGINT 5736 和 kill -SIGUSR1 5736 都能得到正确结果,但是我发送 kill -SIGALRM 5736 程序就终止了。后来查资料得到了解释:
在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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: