執行緒控制-sigwait函式和相關函式解釋
阿新 • • 發佈:2019-02-13
首先看這篇文章學習執行緒和訊號: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