第三季-第15课-信号通讯编程

第15课-信号通讯编程

 

15.1 核心理论

1. 信号

在古老的战场上,信号是最有效,最直接的通讯方式;在linux系统中,信号(signal)同样也是最古老的进程间通讯机制。

2. 信号处理流程

进程A/内核---(1)选择信号-----(2)发送信号-----(3)处理信号----进程B。

3. 信号类型

Linux系统支持的所有信号均定义在/usr/include/asm/signal.h(展示),其中常见的信号有:

SIGKILL:杀死进程

SIGSTOP:暂停进程

SIGCHLD:子进程停止或结束时用来通知父进程

15.2 函数学习

1. 发送信号
(1)函数名

kill

(2)函数原形

int kill(pid_t pid,int sig);

(3)函数功能

向一个进程发送信号(send signal to a process)。

(4)所属头文件

#include<sys/types.h>

#include<signal.h>

(5)返回值

成功:0

失败:-1

(6)参数说明

pid:pid>0,pid参数指向接收信号的进程

sig:指明要发送的信号。

2. 处理信号
(1)函数名

signal

(2)函数原形

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

(3)函数功能

设置信号的处理方式(sets the disposition of the signal signum to handler)。

(4)所属头文件

#include<signal.h>

(5)返回值

成功:返回处理函数指针

失败:SIG_ERR

(6)参数说明

signum:要处理的信号

handler:函数指针,设置对应信号的处理方式。有三种取值:(1)SIG_IGN忽略这个信号不处理,(2)SIG_DFL交给系统去处理,(3)用户自定义的函数:交给用户自定义的函数来处理。

15.3 综合实例编程

A、B进程利用信号通讯。这里我们要一个新的函数pause,下面首先对它进行一个简单的介绍。

(1)函数名

pause

(2)函数原型

int pause(void);

(3)函数头文件

#include<unistd.h>

(4)函数功能

等待信号(wait for signal)

(5)返回值

成功:捕捉了信号返回-1

失败:EINTR

(6)参数

范例:

B进程,接收信号

#include<signal.h>

#include<unistd.h>

void myfuc(int a)

{

         printf("Process B received SIGINT! ");

}

void main()

{

         signal(SIGINT,myfuc);

         pause();

}

当我们运行这段程序的时候,看到终端处于等待的状态。

我们先使用命令的方式,测试接收程序的实现。打开另一个终端首先输入:ps aux命令查看我们运行的改程序的进程,将序列号记住。然后输入命令:kill -n SIGINT 3637

我们会看到操作的起一个终端开始打印:Process B received SIGINT!

A进程,发出信号:

#include<signal.h>

#include<sys/types.h>

#include<stdio.h>

void main(int argc,char *argv[])  /*因为要把进程B的进程号传过来,我们要设置参数*/

{                                   /*argc表示信号个数,argv[]表示信号*/    

         pid_t pid;

         pid = atoi(argv[1]);           /*argv[0]是程序的名字,argv[1]是B进程的进程号*/

         kill(pid,SIGINT);

}

注:pid的获取由命令行来获取,命令行传进来的是一个字符串,pid是个整数,用atoi函数将字符串转换成整数。

运行结果:先运行B进程,然后ps aux查看B进程的进程号(如3710),运行./ap 3710,在等待状态的B进程打印:Process B received SIGINT!

原文地址:https://www.cnblogs.com/free-1122/p/11351127.html