先给自己打个广告,本人的微信公众号正式上线了,搜索:张笑生的地盘,主要关注嵌入式软件开发,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题
一 why
在之前的博文《linux进程间通信(一)----初识篇》中,我们知道了进程间通信主要分为三大类,分别是管道通信,信号通信,以及IPC通信;进程间通信主要是为了不同进程之间的数据共享,信号通信也不例外。
二 what
(1)什么是信号通信,或者说什么是信号机制?
信号是软件层次上对中断机制的一种模拟,是一种异步通信方式。通常如果我们做过单片机开发,嵌入式底层硬件开发,我们都很熟悉硬件中断,它是外设工作时给CPU发送的,是一种异步通信方式。
linux内核通过信号通知进程,不同的信号类型代表不同的事件,Linux对早期的unix信号机制进行了扩展。
(2)查看当前linux下面支持的信号类型
kill -l
(3)进程对信号的处理方式
缺省方式
忽略信号
捕捉信号
(4)信号的相关命令
注意这是我们在console终端下可以输入的命令
1. kill //英文原意是杀死,会让我们中文使用者产生误解,既然是杀死是不是意味着停止进程
//实际上是向一个进程发送信号的意思
kill [-signal] pid // 默认信号是15 SIGTERM
-sig 可指定信号
pid 指定发送对象
举例 kill -9 6437
2. killall
killall [-u user | prog]
prog 指定进程名,注意这里是进程的名字,不是进程pid
user 指定用户名
(5)信号发送函数
1. kill
#include <unistd.h>
#include <signal.h>
int kill(pid_t pid, int sig);
pid : 指定进程号 0代表同组进程;-1代表所有除了INIT进程和当前进程之外的进程
sig : 信号类型
2. raise
#include <unistd.h>
#include <signal.h>
int raise(int sig);
3. alarm
int alarm(unsigned int seconds);
seconds 定时器的时间
成功返回上个定时器的剩余时间,失败返回EOF
经常用来实现超时检测
4. pause
int pause(void);
进程一直阻塞,直到而被信号中断
5. signal
设置信号响应方式,请注意这个函数和kill、killall的区别,我们中文使用者会理解为
发信号,实际上它并不是发信号
#include <unistd.h>
#include <signal.h>
void (*signal(int signo, void(*handler)(int)))(int)
成功返回原先的信号处理函数,失败返回SIG_ERR
signo 要设置的信号类型
handler 指定的信号处理函数;SIG_DFL代表缺省方式;SIG_IGN代表忽略信号
三 how
(1)alarm和pause
读者可以在自己的环境下编译后运行看一下最后的效果,思考,如果将alarm函数注释后再运行,会是什么结果?
#include "stdio.h"
#include "stdlib.h"
#include <unistd.h>
#include "sys/types.h"
#include <signal.h>
int main()
{
alarm(3);
pause();
printf("I have been waken up!\n");
return 0;
}
(2)发送信号signal
编译后运行,分别在console下按下"ctrl+c"和"ctrl+",以及其他任意组合键,看运行情况
#include "stdio.h"
#include "stdlib.h"
#include <unistd.h>
#include "sys/types.h"
#include <signal.h>
void handler(int signo)
{
if (signo == SIGINT) {
printf("I have got SIGINT\n");
}
if (signo == SIGQUIT) {
printf("I have got SIGQUIT\n");
}
}
int main()
{
signal(SIGINT, handler);
signal(SIGQUIT, handler);
while (1) pause();
return 0;
}