Linux进程间通信之信号通信

信号通信是Linux进程间通信的一种方式。
1.什么是信号?
信号是系统响应某些条件而产生的一个事件,接收到该信号的进程会相应地采取一些措施。例如我们在windows系统中想强制结束一个程序我们需要用到的是任务管理器,而在Linux中,我们是通过信号来实现的,运行中的进程捕获到信号并做出相应的行为。

信号的通信其实就是内核向用户空间进程发送信号(只有内核可以发送信号,用户空间进程不可以)

内核中已经存在信号,不需要自己创建
Linux进程间通信之信号通信
2.信号的种类:
在Linux系统*有64种信号。
通过kill -l 命令可以查看。
Linux进程间通信之信号通信

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

Linux进程间通信之信号通信

在执行指令 kill 9 9890 后
进程被杀死
Linux进程间通信之信号通信

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;
}

Linux进程间通信之信号通信

与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;

Linux进程间通信之信号通信