linux 信号

发布时间:2016-12-11 8:44:59 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"linux 信号",主要涉及到linux 信号方面的内容,对于linux 信号感兴趣的同学可以参考一下。

原创:http://blog.sina.com.cn/u/2312748742 一、1、信号是一种软中断,2、信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据,3、收到信号的进程对各种信号有不同的处理方法。4、进程通过系统调用signal来指定进程对某个信号的处理行为。 二、信号 值 处理动作 发出信号的原因 : SIGHUP 1 A 终端挂起或者控制进程终止 SIGINT 2 A 键盘中断(如break键被按下) SIGQUIT 3 C 键盘的退出键被按下 SIGILL 4 C 非法指令 SIGABRT 6 C 由abort(3)发出的退出指令 SIGFPE 8 C 浮点异常 SIGKILL 9 AEF Kill信号 SIGSEGV 11 C 无效的内存引用 SIGPIPE 13 A 管道破裂: 写一个没有读端口的管道 SIGALRM 14 A 由alarm(2)发出的信号 SIGTERM 15 A 终止信号 SIGUSR1 30,10,16 A 用户自定义信号1 SIGUSR2 31,12,17 A 用户自定义信号2 SIGCHLD 20,17,18 B 子进程结束信号 SIGCONT 19,18,25 进程继续(曾被停止的进程) SIGSTOP 17,19,23 DEF 终止进程 SIGTSTP 18,20,24 D 控制终端(tty)上按下停止键 SIGTTIN 21,21,26 D 后台进程企图从控制终端读 SIGTTOU 22,22,27 D 后台进程企图从控制终端写 三、信号的安装处理: void (*signal(int signum, void (*handler))(int)))(int); 该函数有两个参数, signum指定要安装的信号, handler指定信号的处理函数. 该函数的返回值是一个函数指针, 指向上次安装的handler 四、例子: #include<stdio.h> #include<signal.h> int counts=0; void signal_callback(int nums) {  counts++;  printf("Ctrl_C Press numbers: %d\n",counts); } int main() {  int c;  signal(SIGINT,signal_callback);  while((c=getchar())!='\n');  return 0; } 当运行该程序时,按CTRL+C,则会调用回调函数。  五、屏蔽信号 所谓屏蔽, 并不是禁止递送信号, 而是暂时阻塞信号的递送, 解除屏蔽后, 信号将被递送, 不会丢失. 相关API为 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);//sigismember()用来测试参数signum 代表的信号是否已加入至参数set信号集里。如果信号集里已有该信号则返回1,否则返回0。 //信号的屏蔽: int  sigprocmask(int  how,  const  sigset_t *set, sigset_t *oset)); sigprocmask()函数能够根据参数how来实现对信号集的操作, 1)how操作主要有三种: * SIG_BLOCK 在进程当前阻塞信号集中添加set指向信号集中的信号 mask=mask|set * SIG_UNBLOCK 如果进程阻塞信号集中包含set指向信号集中的信号,则解除    对该信号的阻塞  mask=mask & ~set * SIG_SETMASK 更新进程阻塞信号集为set指向的信号集  mask = set 2)set:如果是非空指针,则更改进程的信号屏蔽字。 3)oset如果是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。 返回0表示成功,-1表示出差。故可以由: sigemptyset(&s);  sigprocmask(SIG_BLOCK,NULL,&s); //block 由&s传出。 未决信号可以由 int sigpending(sigset_t *set),通过set传递出来。获取未决信号。0表示成功,-1失败 六、信号在内核中的表示: 信号递达(Delivery):执行信号的处理动作。 信号未决(Pending):信号从产生到递达之间的状态。 --》进程可以选择阻塞(Block)某个信号,被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。   例子: #include<sys/types.h> #include<sys/stat.h> #include <fcntl.h> #include <errno.h> #include <sys/wait.h> #include <signal.h> void signal_callback(int sigNum) {  if(sigNum==SIGRTMIN+2)  {   //Unblock the signal 1;   sigset_t tmp;   sigemptyset(&tmp);   sigaddset(&tmp,SIGRTMIN+1);   sigprocmask(SIG_UNBLOCK,&tmp,0); //block   //--》进程可以选择阻塞(Block)某个信号,被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。因为刚开始时信号1已经被阻塞,因此这个信号将在未决状态。因此当发送信号1即35时将变成未决状态,当发送信号2即36时,如上将信号1进行解阻塞,就会把刚才的信号1执行递达的动作,因此会显示执行printf("recv signal %d\n",sigNum);  }  if(sigNum==SIGRTMIN+1)  {   printf("recv signal %d\n",sigNum);  } } void printfSigSet(sigset_t *tmp) {  int i;  for( i=0;i<=64;i++)  {   if(sigismember(tmp,i))   {    putchar('1');   }   else   {    putchar('0');   }   if (i==0)    putchar('\n');  }  printf("----------------------------------\n"); } int main() {  sigset_t p;  sigset_t s;  signal(SIGRTMIN+1,signal_callback);  signal(SIGRTMIN+2,signal_callback);  //block the signal 1;  sigemptyset(&p);  sigaddset(&p,SIGRTMIN+1);  sigprocmask(SIG_BLOCK,&p,0); //block  while(1)  {   //get which signal is pending   sigemptyset(&s);   sigpending(&s);   printf("pending signal:\n");   printfSigSet(&s);       ////get which signal is  block   printf("block signal:\n");   sigemptyset(&s);   sigprocmask(SIG_BLOCK,0,&s); //block   printfSigSet(&s);   sleep(2);  } }   运行程序时显示: pending signal: 1 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ---------------------------------- block signal: 1 0000000000000000 0000000000000000 0010000000000000 0000000000000000 ----------------------------------   当终端发送 kill -35 进程号。时, pending signal: 1 0000000000000000 0000000000000000 0010000000000000 0000000000000000 ---------------------------------- block signal: 1 0000000000000000 0000000000000000 0010000000000000 0000000000000000 ---------------------------------- 当发送 kill -36 给进程时: recv signal 35 pending signal: 1 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ---------------------------------- block signal: 1 0000000000000000 0000000000000000 0010000000000000 0000000000000000 ----------------------------------

上一篇:如何单步调试&nbsp;dll&nbsp;文件里面函数
下一篇:4629. A+B Again

相关文章

关键词: linux&nbsp;信号

相关评论