信号:

中断:中止、暂停当前正在执行的进程,转而去执行其它的任务。
         分类:1.硬中断:来自硬件设备的中断
                     2.软中断:来自其它程序的中断

而信号就属于软件中断,它提供了一种处理异步事件的方法。

信号的分类:

不可靠信号(这里不可靠指的是信号可能会丢失)
        1.编号小于SIGRGMI(34)的信号都是不可靠的,这些信号是建立在早期的信号机制上的,一个事件发生可能会产生多次信号。
        2.不可靠信号不支持排除,在接收信号的时候可能会丢失,如果一个发给一个进程多次,它可能只接收到一次,其它的可能就丢失了。    
        3.进程在处理这种信号的时候,哪怕设置的信号处理函数,当信号处理函数执行完毕后,会再次恢复成默认的信号处理方式。

可靠信号(实时)
        1.位于[SIGRGMI(34),SIGRTMAX(64)]区间的都是可靠信号。
        2.可靠信号支持排除,不会丢失。
        3.无论是可靠信号还是不可靠信号都是通过:kill、signal、sigqueue、sigaction函数进行处理。

LInux下可以通过 kill -l 查看信号列表

信号处理方式:

1.忽略:大多数信号都可使用这种方式进行处理,但SIGKILL、SIGSTOP这两个信号绝对不能被忽略:它们向内核和超级用户提供了使进程终止或停止的可靠方法。

2.终止:大多数信号的系统默认处理方式都是终止。

3.终止+core:表示在进程当前工作目录的core文件中复制了该进程的内存映像,大多数UNIX系统调试程序都使用core文件检查进程终止的状态。ubuntu默认不产生core,需要使用命令设置:ulimit -c unlimited 这样运行程序后就可以通过gdb ./a.out core 来查看程序出错的位置(gcc编译时要加上-g 产生调试信息)

4.捕获并处理:为了做到这一点,要通知内核在某种信号发生时,调用一个用户函数,在用户函数中执行用户想对这个信号进行的处理(signal(),注册信号处理函数)。注意,SIGKILL/SIGSTOP这两个信号同样也不能被捕获

signal函数:

头文件: #include <signal.h>

其原本的原型为

void (*signal(int signo,void (*func)(int)))(int);

上述这种形式过于复杂,一般都采用下列这种形式:

typedef void (*sighandler_t)(int);
sighandler_t  signal(int  signum, sighandler_t handler);

函数功能:注册一个信号处理函数
            signum:信号的编号,可以直接写数字,也可以使用系统提供的宏。
            handler:1.函数指针,即用户想要对此信号进行处理的函数
                              2.SIG_IGN 忽略信号
                              3.SIG_DFL 恢复信号默认的处理方式
            返回值:之前的信号处理方式
                            函数指针、SIG_IGN、SIG_DFL、SIG_ERR

子进程的信号处理:
               1.当一个进程调用fork时,因为子进程在开始时复制父进程的存储映像,信号捕捉函数的地址在子进程中是有意义的,所以子进程继承父进程的信号处理方式。
               2.特殊的是exec,因为exec运行新的程序后会覆盖从父进程继承来的存储映像,那么信号捕捉函数在新程序中已无意义,所以exec会将原先设置为要捕捉的信号都更改为默认动作,但是,exec创建的子进程会继承父进程的信号忽略处理

演示一个ctrl+Z、ctrl+C、ctrl+\ 都结束不了的程序

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>int main(int argc, char const *argv[])
{signal(SIGINT,SIG_IGN);//忽略SIGINT信号signal(SIGQUIT,SIG_IGN);//忽略SIGQUIT信号signal(SIGTSTP,SIG_IGN);//忽略SIGTSTP信号printf("My pid:%d",getpid());for(;;){printf(".\n");sleep(1);}return 0;
}

想要杀死这个进程,就要通过kill -9 +打印的进程号,或者直接关掉终端即可(终端为此进程的父进程) 。

信号的发送方式:

1、键盘
        Ctrl+c 终端中断信号
        Ctrl+z 终端暂停信号,fg命令再次开启
        Ctrl+/ 终端退出信号
    2、错误产生的信号
           除0
           非法内存访问
           硬件总线
    3、命令产生的信号
              kill -信号 进程号
              killall -信号 程序名(杀死所有同名的进程)。
    4、函数产生的信号

kill函数:

int kill(pid_t pid, int sig);

函数功能:向指定的进程发送信号
            pid:进程号
            sig:信号
                    0表示空信号,不会向进程发送信号,但是会测试是否能向pid发送信号,这样可以检测一个进程是否存在
                    返回-1表示进程不存在,errno会被设为ESRCH。
            返回值:-1,说明进程不存在

raise函数:

     int raise(int sig);

功能:向自己发送信号

下面演示一下利用signal(),kill(),以及fork()创建的子进程会继承父进程信号处理方式的例子

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>void sigsegv(int num)//用户定义的段错误信号处理函数
{printf("Receive segment fault signal:%d\n",num);exit(0);
}int main()
{pid_t pid;if(SIG_ERR == signal(SIGSEGV,sigsegv))//signal函数,表示对SIGSEGV的处理{perror("signal");return -1;}if (0 == fork())//创建子进程{printf(" son pid:%d my father pid:%d\n",getpid(),getppid());while(1);}printf(" father pid:%d my father pid:%d\n",getpid(),getppid());while(1){sleep(1);puts("Please input pid to message:");scanf("%d",&pid);//输入需要传递段错误信号的进程kill(pid,SIGSEGV);//向pid进程发送信号}return 0;
}

结果显示:

子进程pid为21289 父进程pid为21288,第一次向子进程发送段错误信号,子进程立马通过signal函数调用了用户函数对段错误信号进行处理,如图即为打印接受到了段错误并退出,第二次向父进程发送段错误信号同理,程序结束。

信号(signal,kill,raise)相关推荐

  1. Linux进程间通信第三讲 信号signal kill

    目录 三.信号(signal) 3.1 概念 3.2 信号的处理 3.3 信号的发送 3.4 信号的屏蔽 三.信号(signal) 3.1 概念 信号本质上是一种软件中断 软件触发的中断.和硬件的处理 ...

  2. 子进程信号继承;kill+raise+alarm+pause+信号发生接收和处理+信号屏蔽

    子进程对父进程信号继承情况 fork创建子进程,但子进程没有exec 在fork子进程之前: 如果父进程调用signal设置了某个信号的处理方式的话,那么fork出的子进程会继承父进程对该信号设置的处 ...

  3. Linux 信号signal处理函数--转

    alarm(设置信号传送闹钟) 相关函数 signal,sleep 表头文件 #include<unistd.h> 定义函数 unsigned int alarm(unsigned int ...

  4. 非常好的一篇对linux信号(signal)的解析

    [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执 ...

  5. Linux 信号signal处理函数

    alarm(设置信号传送闹钟) 相关函数 signal,sleep 表头文件 #include<unistd.h> 定义函数 unsigned int alarm(unsigned int ...

  6. Linux异步之信号(signal)机制分析

    From:http://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html From:http://kenby.iteye.com/blog/11 ...

  7. Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)

    整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道 ...

  8. linux信号11sigtstp,Linux信号(signal)机制

    信号(signal)是一种软中断,信号机制是进程间通信的一种方式,采用异步通信方式 一.信号类型 Linux系统共定义了64种信号,分为两大类:可靠信号与不可靠信号,前32种信号为不可靠信号,后32种 ...

  9. 信号--Signal

    信号–Signal 信号的作用就相当于神经系统,来帮助操作系统进程运行过程中遇到的各种意外. 在Linux系统中通过命令kill -l来查看所有信号. 信号产生的方式: 1. 通过终端按键产生信号(键 ...

最新文章

  1. RH系列linux上编译android2.3(gingerbread)
  2. mysql视频教程siki_siki老师MySQL数据库从零到精通,资源教程下载
  3. html5 绘制图形,HTML5绘制几何图形
  4. CRM学习笔记(一)
  5. 关于 Linux 操作
  6. 人工智能 7.专家系统
  7. photoshop 插件_适用于Web设计人员的10+个免费Photoshop插件
  8. 谷歌地图高精度模型提取4(完结篇)
  9. MATLAB绘图 最大化全屏后保存
  10. wpa_supplicant Day1: supplicant基本概念
  11. ​历经 33 天,终于拿到了心仪的 Offer
  12. SQL 查询语句报错
  13. Flask+ZUI 开发小型工具网站(三)——登录功能
  14. 如何下载网页中的图片
  15. 【连接池】Tomcat 连接池中 maxActive,maxWait,maxAge,testOnBorrow,testWhileIdle等选项的作用
  16. EasySwoole 基础入门
  17. 大学一定要拿计算机证书吗,大学期间,一定要拿到这些证书,不要到了毕业才后悔...
  18. 2021年高考成绩查询湖北状元,2021年武汉高考状元名单公布,武汉高考状元学校资料及最高分...
  19. UVa 10101 - Bangla Numbers
  20. 红蓝对抗之域名搜集方法总结

热门文章

  1. 人力资源数据分析师前景_数据分析师的前途在哪?
  2. 数据分析师有发展前景吗?
  3. cron每小时执行一次的表达式
  4. 白鹭[egret]项目目录介绍)
  5. 【XR】为挑战性环境优化6DoF控制器追踪
  6. 银行网申计算机技能怎么填,邮政储蓄银行网申填写技巧分享二
  7. android网络传输唤醒系统,Android手机唤醒群晖NAS系统
  8. 常见(XSS|CSRF)六大Web安全攻防解析
  9. 21个经典的哲理故事
  10. java httpClient使用代理实现互联网公网访问