信号使用方法

来源:互联网 发布:数据库事务使用场景 编辑:程序博客网 时间:2024/04/28 15:28
                                             信号基本使用方法

信号:
首先计算机是一个很会营造假象的机器,它欺骗每一个进程,线程。使他们误以为自己就是唯一使用资源的进线程,但是者也造成了一个问题,进线程们都变得比较自我,想让他们互相之间通信,或者我们和他们通信就必须使用一些 “手段“ 。向他们发送信号就是一种很好的方法。
首先在LINUX下就有很多信号,当前共有64个其中32,33号信号暂时没有设定。
$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为34 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。
一般使用kill -signum PID 来发送信号。
信号虽然多但是很大一部分可以根据他们的名字来分辨他们功能。
kill( )信号发送函数:

int sig_send(pid_t id,int sig){   if(kill(id,sig)){       printf("mission failed [%d]\n",errno);    }    return 0;}

这个函数接受俩个参数,一个是进程的id,另一个是信号名称。使用Kill 函数将信号发送给id进程。

sigalarm & pause
#include

#include <apue.h>int main(){    if(!alarm(5)){    }    pause();}

这个程序简单的展现了这两个函数配合使用的效果。

signal( )函数:
#include

 void int_hander(int sig){    printf("got signal : %d\n",sig);    exit(0);}int main(){    int sig = 1;    while(1){       if(SIG_ERR == signal(sig,int_hander)){           printf("signale error %d\n",sig);       }     sleep(1);    }
   #include <signal.h>   int sigemptyset(sigset_t *set);   int sigfillset(sigset_t *set);   int sigaddset(sigset_t *set, int signum);   int sigdelset(sigset_t *set, int signum);   int sigismember(const sigset_t *set, int signum);   这是信号修改一族的函数,分别的作用为:    这里的信号集都是要屏蔽的信号         int sigemptyset(sigset_t *set);清空整个信号集    int sigfillset(sigset_t *set);添加所有信号进信号集    int sigaddset(sigset_t *set, int signum);追加signum信号进信号集    int sigdelset(sigset_t *set, int signum);从信号集中删除信号signum    int sigismember(const sigset_t *set, int signum);用来测试参数signum是否已经添加到信号集    #include <signal.h>   int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);   这个函数主要是用来设置信号集的,其中how 有三个参数   SIG_BLOCK  追加屏蔽信号到信号屏蔽关键字里去   SIG—UNBLOCK 解放传进来的信号   SIG_SETMASK 接受传参的信号位屏蔽信号 
#include <apue.h>void sigmask_blockall(){    sigset_t sigset,oldset;    sigemptyset(&sigset);    sigemptyset(&oldset);    sigfillset(&sigset);    sigdelset(&sigset,SIGKILL);    sigdelset(&sigset,SIGSTOP);    if(sigprocmask(SIG_SETMASK,&sigset,&oldset)){        printf("sigprocmask error : %d\n",errno);    }}void sigmask_blocksig(int sig){    sigset_t sigset,oldset;    sigemptyset(&sigset);    sigemptyset(&oldset);    sigaddset(&sigset,sig);    if(sigprocmask(SIG_BLOCK,&sigset,&oldset)){        printf("sigprocmask error : %d\n",errno);    }}void sigmask_freeall(){    sigset_t sigset,oldset;    sigemptyset(&sigset);    sigemptyset(&oldset);    if(sigprocmask(SIG_SETMASK,&sigset,&oldset)){        printf("sigprocmask error : %d\n",errno);    }}void usage(char *cmd){    printf("Usage : %s <1|2|3>\n",cmd);}int main(int ac,char **av){    int route = 0;    if(1 >= ac){        usage(av[0]);        return 1;    }    route = atoi(av[1]);    switch(route){        case 1:        sigmask_blockall();        break;        case 2:        sigmask_blocksig(SIGINT);        break;        case 3:        sigmask_freeall();        break;        default:        usage(av[0]);        //printf("Only 1,2,3 is OK\n");        break;    }//end switch    while(1){        sleep(1);    }}

这个函数展示了设置信号屏蔽字的三种方式。

sigpending()
#include

#include <apue.h>void sig_hander(int sig){    printf("got sig : %d\n",sig);}void sig_set(sigset_t *set,int sig){    if(NULL == set){        return;    }    sigemptyset(set);    if(SIGRTMAX < sig){        sigfillset(set);    }else{        sigaddset(set,sig);     }}int main(){    sigset_t set,old,pend;    int sig = 1;    while(sig < 65){        if(SIG_ERR == signal(sig,sig_hander)){            //error        }        ++sig;    }    sig_set(&set,65);    if(sigprocmask(SIG_BLOCK,&set,NULL)){        //error    }    sigemptyset(&pend);    /* 本函数将挂起,直到某个信号出现打断。     * 函数返回后,屏蔽字将还原。     * 函数返回前,进程的屏蔽字,将被临时替换。     */    sigsuspend(&pend);    printf("suspend end\n");    while(1){        sleep(1);    }    return 0;}
0 0
原创粉丝点击