信号的基本概念

1.信号

信号主要用来通知进程发生了异步事件,而不会给进程传递任何数据。信号总共有62个,前32个被称为普通信号,34-64被称为实时信号。通常只关心普通信号。

2.信号的产生

1> 键盘

通过组合键发送一个信号,一定是给前台进程的。例如ctrl+c

2>用系统函数发送信号

可以给指定进程发送信号,例如kill命令用kill()函数实现,abort函数是当前进程接收到信号而异常终止。raise自己给自己发送信号。

3>由软件条件产生

alarm(时间数),当alarm完成后直接终止进程。

3.信号的处理

1>忽略

2>执行信号默认处理方式

3>自定义方式:捕捉信号

使用sighandler_t signal(int signum, sighandler_t handler);

注:第一个参数是哪个信号,第二个参数是捕捉信号的函数名

4.阻塞信号

1>实际执行信号处理动作称为信号递达。

2>信号从产生到递达之间的状态称为信号未决。

进程可以选择阻塞某个信号,被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。(忽略与阻塞不同,忽略是在信号递达之后)

信号不是立即处理的,是在一个合适的点上处理的。除了9号信号。

信号在内核中表示示意图:

一个信号没有pending,可以被block。block与pending没有关系。

信号代码举例:

  1 #include<stdio.h>
  2 #include<signal.h>
  3 void show(sigset_t* sig_pending)//展示未决的信号
  4 {
  5   int i=1;
  6   for(i=1;i<32;++i)
  7   {
  8     if(sigismember(sig_pending,i))
  9     {
 10           printf("1");
 11     }
 12 
 13    else
 14   {
 15         printf("0");
 16    }
 17 
 18 
 19    }
 20 printf("\n");
 21 }
 22 
 23 void handler(int sig)//捕捉递达的信号
 24 {
 25   printf("I  see you! %d\n",sig);
 26 
 27 
 28  }
 29 
 30 int main()
 31 {
 32      sigset_t sig_mask;
 33      sigset_t sig_old;
 34      sigset_t sig_pending;
 35      sigemptyset(&sig_mask);
 36      sigemptyset(&sig_old);
 37      sigemptyset(&sig_pending);
 38      sigaddset(&sig_mask,SIGINT);//将2号信号放入信号集中阻塞
 39      sigprocmask(SIG_SETMASK,&sig_mask,&sig_old);
 40      int count=10;
 41     signal(SIGINT,handler);
 42      while(1)
 43      {
 44         sigpending(&sig_pending);//获取当前进程信号集,与pending有关
 45         show(&sig_pending);
 46         sleep(1);
 47        if(count<0)
 48         {
 49           sigprocmask(SIG_SETMASK,&sig_old,NULL);//恢复2号信号
 50         }
 51         count--;
 52      }
 53    return 0;
 54 }

用户模式与内核模式切换关于信号

5.捕捉信号

1>sigaction

#include <signal.h>

int sigaction(int signo, const struct sigaction *act, struct

sigaction *oact);

sigaction函数可以读取和修改与指定信号相关联的处理动作。调用成功则返回0,出错则

返回- 1。signo是指定信号的编号。若act指针非空,则根据act修改该信号的处理动作。

若oact指针非 空,则通过oact传出该信号原来的处理动作。act和oact指向sigaction结

构体

.

  1 #include<stdio.h>
  2 #include<signal.h>
  3 #include<string.h>
  4 void handler(int sig)
  5 {
  6   printf("I am that signal...%d\n",sig);
  7 } 
  8 int main()
  9 {
 10    struct sigaction old;
 11    struct sigaction act;
 12    act.sa_handler=handler;//自定义处理信号动作
 13    act.sa_flags=0;
 14    sigemptyset(&act.sa_mask);
 15    memset(&old,‘\0‘,sizeof(old));
 16    sigaction(SIGINT,&act,&old);对2号信号设置
 17     while(1)
 18     {
 19      printf("I am waiting  a signal....\n");
 20      sleep(2);
 21      }
 22      return 0;
 23 }

2>pause

int pause(void);

pause函数使调用进程挂起直到有信号递达。如果信号的处理动作是终止进程,则进程终

止,pause函数没有机会返回;如果信号的处理动作是忽略,则进程继续处于挂起状态,pause

不返回;如果信号的处理动作是捕捉,则调用了信号处理函数之后pause返回-1,errno设置为

EINTR, 所以pause只有出错的返回值(想想以前还学过什么函数只有出错返回值?)。错误码

EINTR表 示“被信号中断”。

下面我们用alarm和pause实现sleep(3)函数,称为mysleep。

1 #include<stdio.h>

2 #include<signal.h>

3 #include<string.h>

4 void handler(int sig)

5 {

6 //donothing

7 }

8 void  my_sleep(int time)

9 {

10  struct sigaction act,old;

11  act.sa_handler=handler;

12  act.sa_flags=0;

13  sigemptyset(&act.sa_mask);

14  sigaction(SIGALRM,&act,&old);

15  alarm(time);//设置闹钟

16  pause();

17  int ret=alarm(0);//清理闹钟

18  sigaction(SIGALRM,&old,NULL);恢复信号

19

20 }

21 int main()

22 {

23     while(1)

26      {

27      printf("I am waiting  a signal....\n");

28      my_sleep(5);

29      }

30      return 0;

31 }

程序结果:每隔5秒打印一次信息,相当于调用了sleep()函数。

程序分析:

1. main函数调用mysleep函数,后者调用sigaction注册了SIGALRM信号的处理函数

sig_alrm。

2. 调用alarm(nsecs)设定闹钟。

3. 调用pause等待,内核切换到别的进程运行。

4. nsecs秒之后,闹钟超时,内核发SIGALRM给这个进程。

5. 从内核态返回这个进程的用户态之前处理未决信号,发现有SIGALRM信号,其处理函数

是sig_alrm。

6. 切换到用户态执行sig_alrm函数,进入sig_alrm函数时SIGALRM信号被自动屏蔽,

从sig_alrm函数返回时SIGALRM信号自动解除屏蔽。然后自动执行系统调用sigreturn再次进入 内核,再返回用户态继续执行进程的主控制流程(main函数调用的mysleep函数)。

7. pause函数返回-1,然后调用alarm(0)取消闹钟,调用sigaction恢复SIGALRM信号

以前的处理 动作。

时间: 2024-10-10 05:20:18

信号的基本概念的相关文章

[linux环境编程] 信号的基本概念与操作函数

[linux环境编程] 信号的基本概念与操作函数 一.基本的概念 1.中断的基本概念 中断是指在CPU正常运行期间,由于内外部事件或由程序预先安排的事件引起的CPU暂时停止正在运行的程序,转而为该内部或外部事件或预先安排的事件服务的程序中去,服务完毕后再返回去继续运行被暂时中断的程序. 而在Linux中通常分为外部中断(又叫硬件中断)和内部中断(又叫异常). 硬中断:来自硬件设备的中断 软中断:来自其它程序的中断 2.信号的基本概念 信号是软件中断,提供了一种处理异步事件的方法,可以把他看作是进

(原) 信号(上)------信号的基本概念

一.信号的介绍 信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式.但是信号和中断还是有所区别的,主要的区别体现在: (1):中断有优先级,信号没有,所有的信号都是平等的: (2):中断处理程序是在内核态运行,而信号处理程序是在用户态运行: (3):中断响应是及时的,而信号响应则有较大的延时. 二.信号的产生 (1):用户在终端按下某些键时,终端驱动程序会发送信号给前台进程,例如ctr+c产生SIGINT,  ctr + \产生SIGQUIT信号: (2):硬件异常产生信号,这些条件由硬

linux下Bash局部变量及信号捕捉等概念解释

1.脚本配置文件 /etc/rc.d/init.d/服务脚本可支持配置文件,并放置在/etc/sysconfig/下同名的配置文件 2.局部变量:只对本函数内部等有效,关键字为local 以两个脚本显示变量带或不带local时的区别 2.1编写如下脚本:vim A1.sh #!/bin/bash A=1 SUM() { A=8 } SUM  调用函数 for I in `seq $A 10`; do echo -n "$I   " done echo ./A1.sh:执行脚本显示结果如

UNIX高级环境编程(13)信号 - 概念、signal函数、可重入函数

信号就是软中断. 信号提供了异步处理事件的一种方式.例如,用户在终端按下结束进程键,使一个进程提前终止. ? 1 信号的概念 每一个信号都有一个名字,它们的名字都以SIG打头.例如,每当进程调用了abort函数时,都会产生一个SIGABRT信号. 每一个信号对应一个正整数,定义在头文件<signal.h>中. 没有信号对应整数0,kill函数使用信号编号0表示一种特殊情况,所以信号编号0又叫做空信号(null signal). 下面的各种情况会产生一个信号: 当用户在终端按下特定的键时,会产生

linux信号基本概念及如何产生信号

linux信号基本概念及如何产生信号 摘自:https://blog.csdn.net/summy_j/article/details/73199069 2017年06月14日 09:34:21 阅读数:4131 标签: linux信号 更多 个人分类: Linux 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/summy_J/article/details/73199069 阅前须知 本文的主要内容有: 1.信号的基本概念(包括进程对信号的3

Linux 信号signal处理机制(ZZ)

http://www.cnblogs.com/taobataoma/archive/2007/08/30/875743.html 信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 本节先介绍信号的一些基本概念,然后

Linux 信号signal处理机制

信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 本节先介绍信号的一些基本概念,然后给出一些基本的信号类型和信号对应的事件.基本概念对于理解和使用信号,对于理解信号机制都特别重要.下面就来看看什么是信号. 1.基本

浅析Linux中的信号机制(一)

有好些日子没有写博客了,自己想想还是不要荒废了时间,写点儿东西记录自己的成长还是百利无一害的.今天是9月17号,暑假在某家游戏公司实习了一段时间,做的事情是在Windows上用c++写一些游戏英雄技能的逻辑实现.虽然时间不算长,但是也算学了一点东西,对团队项目开发流程也有了一个直观的感受,项目里c++11新特性也有用到不少,特别是lambda表达式,STL的一些容器和算法也终于有了可以实践的地方.由于自己比较喜欢Linux C,也就没有做留下的打算,现在回到了学校,好好复习一段时间,准备一下校招

信号(signal)

一 信号的基本概念 信号机制是进程间相互传递消息的一种方法,信号全称软中断信号,也有人称作软中断,从它的命名可以看出,它的使用很像中断,所以,信号是进程控制的一部分. (1)进程之间可以通过系统调用kill发送软中断信号 (2)内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件. 注:信号指示通知给进程发生了什么事,并不给进程传递数据. 为了理解信号,我们从熟悉的场景说起 用户输入指令,在shell下启动一个前台进程. 用户按下Ctrl+C,此时硬盘驱动产生一个中断给Linux内核.