4412开发板运行之进程通讯专题 | 信号通讯

在iTOP4412开发板运行中,当咱们在win上遇到一个没有办法正常关闭的软件的时候,咱们能够打开任务管理器,强制结束这个进程,同理。在linux上也有相似的功能,好比从终端敲入ctrl+c组合键来产生一个信号,当运行中的进程捕捉到这个信号后就会作出反应。linux

咱们在win上可使用快捷键进入任务管理器,那么linux中会在哪些状况下会产生信号呢?函数

那么linux有多少种信号呢,咱们能够经过命令kill命令来查看,以下图:blog

 经过上面的截图咱们能够发现,一共有64种信号,每一个信号都是以sig开头,信号的名称是在signal.h中定义的。进程

本次文章主要涉及到三个内容,一,信号的发送,二,信号的接收,三,信号的处理。开发

第一部分:信号的发送原型

咱们经过一个小例子来认识下信号的发送:io

这个程序主要用到了kill函数, 由于用户空间是不具有发送信号的能力的,只有内核才能够发信号,内核有那么多信号,咱们要发哪一个信号,而且发给谁呢?那么咱们就须要先告诉内核进程PID,信号ID是多少,kill函数就帮咱们解决了这个问题,函数原型:编译

因此在上面的例子中,咱们就能够经过kill函数来向内核发送一次产生信号的请求。 软件

咱们再来看一个和kill函数很像的函数,raise函数 ,与kill函数不一样的是,它没有第一个参数,他不知道要发信号给谁,因此他只能发信号给本身。咱们来看下这个例子:终端

编译并运行:

函数原型:

从kill和raise的函数原型上看,raise没有pid这个参数,因此raise是能够经过kill来实现的。等价于:

还有一个须要了解的函数alarm函数,与raise函数不一样的是,他只能发alarm信号,而且能够定时发送信号,而raise是马上让内核发信号。因此这个函数的参数没有pid号,也没有信号ID,只有一个延迟的秒数。须要注意的是,一个进程只能有一个alarm时间,函数原型:

第一部分信号发送总结:

用户空间不能发送信号,是经过系统调用函数告诉内核发什么信号,发给谁,让内核来发送的,只有内核才能够发信号。可使用kill,raise,alarm函数来让内核发送信号。

第二部分信号接收

咱们可使用pause来接收信号,pause函数使该进程暂停让出CPU。咱们来看下下面这个例子,当咱们在键盘上按下ctrl+c的时候,程序收到SIGINT信号会被唤醒,而后执行fun函数,处理完以后再返回继续运行该程序,不按则只打印process start(进入睡眠状态)。

 

函数原型:

第三部分信号处理

信号的处理有三种方式,分别为:1,忽略,就是收到信号后,什么也不作,不处理。2,按照默认的方式处理。3,捕获并处理,捕获到信号后,执行咱们本身想执行的代码。咱们先来看下signal函数:

第一种处理方式,忽略:

咱们来看下这个例子。

编译并运行,由于咱们使用的参数为SIG_IGN,因此咱们按下ctrl+c的时候并不能中断程序运行.

第二种处理方式,按照默认的方式处理,咱们把上个例子中的参数改为SIG_DFL,以下:

编译并运行,当咱们按下ctrl+c的时候,会中断咱们程序。

第三种处理方式,执行咱们本身的代码:

当咱们按下ctrl+c的时候,会进去到fun函数。

三个部分总结:

1,咱们可使用kill命令来查看有多少个信号,在这么多信号中,咱们要格外记住如下几个:

 2,用户空间不能发送信号,信号的产生来自内核,让内核产生信号的方式有:经过键盘输入ctrl+c等。当程序运行出错时,内核会给进程发送一个信号,如浮点溢出等,还有就是一个程序能够经过调用函数来给另一个进程发信号,如kill。

3,进程收到信号后,能够忽略,或者按照默认的方式处理,或者按照本身的处理函数来处理,signale是永久注册的,每次都有效,若是不想的话这样可使用sigaction。

相关文章
相关标签/搜索