Linux进程间通信之信号通信
信号通信是Linux进程间通信的一种方式。
1.什么是信号?
信号是系统响应某些条件而产生的一个事件,接收到该信号的进程会相应地采取一些措施。例如我们在windows系统中想强制结束一个程序我们需要用到的是任务管理器,而在Linux中,我们是通过信号来实现的,运行中的进程捕获到信号并做出相应的行为。
信号的通信其实就是内核向用户空间进程发送信号(只有内核可以发送信号,用户空间进程不可以)
内核中已经存在信号,不需要自己创建
2.信号的种类:
在Linux系统*有64种信号。
通过kill -l 命令可以查看。
3.信号通信的框架:
(1)信号的发送:kill ,raise ,alarm
(2)信号的接收:pause ,sleep ,while(1)
(3)信号的处理:signal
(1)信号的发送:
kill 函数:发送信号给任意进程
函数名 | kill |
---|---|
头文件 | #include <signal.h> ,#include<sys/types.h> |
函数原型 | int kill (pid_t pid,int sig) |
参数 | pid ----- 1.正数:要接收信号的进程的进程号。 |
2. 0:信号被发送到所有和pid 进程在同一个进程组的进程 | |
3. -1 :信号被发送给所有在进程表中的进程(除了进程号最大的进程除外) | |
sig :信号的种类 | |
函数返回值 | 成功:0 ,出错:-1 |
举个栗子:
在当前目录下运行一个死循环进程./a.out
在执行指令 kill 9 9890 后
进程被杀死
raise函数:发送信号给自己
函数名 | raise |
---|---|
头文件 | #include <signal.h> ,#include <sys/types.h> |
函数原型 | int raise(int sig) |
参数 | sig : 信号的种类 |
返回值 | 成功:0,错误:-1 |
alarm 函数:闹钟信号发送函数,接受到信号后默认处理终止程序。
函数名 | alarm |
---|---|
头文件 | #include <unistd.h> |
函数原型 | unsigned int alarm(unsigned int seconds) |
参数 | seconds:指定的秒数 |
返回值 | 成功:若之前已经调用过alarm函数且未结束,返回上一个闹钟的时间,否则0。错误:-1 |
举个栗子:
int main(){
int i;
printf("alarm have ready\n");
alarm (5);
printf("alarm have send\n");
for(i = 0;i < 9;i++){
sleep(1);
printf("i = %d\n",i);
}
return 0;
}
与raise 函数比较:
相同点:通过内核发送信号到当前进程
不同点:alarm只会发送SIGALARM信号,且延时一定的时间,raise函数则立即发送
(2)信号的接收:
pause 函数:
函数名 | pause |
---|---|
头文件 | #include <unistd.h> |
函数原型 | int pasue(void) |
返回值 | 成功:0。错误:-1 |
pause函数会使进程处于睡眠状态(S)
sleep 函数
while(1)
(3)信号的处理:signal
当进程收到信号后:
1.进程的默认处理方式:A.忽略 B.终止进程 C.暂停(内核为用户设置的默认处理方式)
2.自己的处理方式:signal 函数
将自己的处理方式告诉内核,当收到信号后,采用自己的处理方式
函数名 | signal |
---|---|
头文件 | #include <signal.h> |
函数原型 | void (*signal (int signum,void(handler)(int)))(int) |
参数 | signum:指定信号 |
handler:1.SIG _IGN:忽略该信号 | |
2.SIG _DFL:采用系统默认的处理方式 | |
3.SIG _DFL:自定义信号处理指针 | |
返回值 | 成功:之前设置的信号处理方式。错误:-1 |
signal 函数有两个参数:
第一个参数是整型变量(信号值)
第二个参数是一个函数指针,是我们自己写的处理函数,该函数返回值是一个函数指针
有几个signal函数就按最新的函数处理
举个栗子:
void myfun(int signum){
int i;
for(i = 0;i<4;i++){
sleep(1);
printf("in myfun \n");
}
return ;
}
int main(){
int i;
signal(14,myfun); //定义信号的自己处理方式
alarm (5);
printf("alarm have send\n");
for(i = 0;i < 9;i++){
sleep(1);
printf("i = %d\n",i);
}
return 0;