27-进程通信

进程通信

进程间通信的方法:

1.管道

2.信号

3.消息队列

4.共享内存

5.信号灯

管道

无名管道:

只能用于具有亲源关系的进程间通信

函数接口:

pipe

int pipe(int pipefd2)

功能:

创建一段用于进程间通讯的内核缓存区

参数:pipedf0: 读文件描述符

pipedf1: 写文件描述符

返回值:成功返回0

失败返回-1

管道特性:

1.管道中如果有写端

管道中有数据则直接读出

管道中没有数据则阻塞等待直到数据写入将数据读出

2.管道中没有写端

管道中有数据则直接读出

管道中没有数据,则直接结束,不需要阻塞等待

3.管道中有读端

如果管道中没有写满64K,直接写入数据

如果管道中写满则需要有数据读出才能继续写入

4.管道中没有读端

写入数据会产生管道破裂的错误,使进程直接退出

有名管道:

可以用于任意两个进程间的通信

必须两端同时加入才能向下执行,如果只有一端,则阻塞等待直到另一端加入

阻塞效果,mkfifo创建的文件,必须同时启动open(O_RDONLY)以及open(O_WRONLY),否则另一端为阻塞

FIFO 的 open 是同步握手操作:O_WRONLY 必须等到另一个进程的 O_RDONLY 才能返回。在同一个进程中顺序调用两者,必然导致死锁。正确做法是使用 fork 分离进程,或利用多进程/多终端配合打开。

mkfifo;

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);

功能:创建一个有名管道 管道文件的路径名(如 "/tmp/myfifo")

参数:pathname: 管道名字

mode: 创建管道的权限(同 open 的权限位,如 0666)

返回值:成功返回0

失败返回-1

信号:

1.内核层与应用层通信的一种机制

2.应用层收到信号的处理方式:

1缺省:按照默认的方式处理信号

2忽略:不处理信号

3捕捉:按照指定的方式处理信号

3.信号的种类, kill -l查看

SIGINT信号,键盘可以输入3信号之一,ctrl + c,

SIGQUIT信号,从键盘输入ctrl + \

SIGKILL信号,不能被忽略和捕捉,只能按照默认方式执行处理

SIGSEGV信号:段错误信号

SIGPIPE信号,管道破裂

SIGALRM信号,定时时间到达

SIGCHLD, 子进程结束信号

SIGSTOP, 暂停信号

SIGTSTP,挂起信号,让进程暂停执行。ctrl + z

SLGIO, 异步IO

4.函数接口:

signal:

#include <signal.h>

typedef void (*sighandler_t)(int); 函数指针类型名字重新设置为sighandler_t

sighandler_t signal(int signum, sighandler_t handler);

功能:改变信号的处理方式

参数:signum信号编号

handler:

SIG_IGN 忽略信号

SIG_DFL 缺省(默认)处理信号,恢复信号为系统默认行为(如终止、暂停等)

捕捉:自定义函数 捕捉信号 信号发生时,调用你写的函数

SIGKILL 9 强制终止(不可捕获) kill -9 <PID>

SIGSTOP 19 强制暂停(不可捕获) kill -STOP <PID>

返回值:

成功 返回之前对该信号设置的处理函数指针(可能是 SIG_DFL、SIG_IGN 或之前自定义的函数地址)

失败 返回 SIG_ERR(即 (sighandler_t)-1),并设置 errno

pause:

#include <unistd.h>

int pause(void);

功能:让当前进程暂停执行(进入睡眠状态),直到收到一个信号,且该信号的处理方式不是忽略。

返回:始终返回 -1 pause() 正常工作时永远不会返回,只有被信号中断后才返回,并且总是返回 -1,同时设置 errno = EINTR

signal(SIGINT, handler)

但是handler什么都不写,只捕捉信号,不处理

sleep()实现的基础

alarm

#include <unistd.h>

unsigned int alarm(unsigned int seconds);

功能:用于设置定时器的函数,它会让内核在指定的秒数后,向当前进程发送 SIGALRM 信号。就发一次

参数:时间秒

返回:返回之前设置的闹钟剩余的秒数(如果之前没有设置,返回 0)

sleep的实现,pause + alarm, 用完之后别忘了恢复默认

相关推荐
_upupup7 小时前
Linux的调试工具——gdb/cgdb
linux·服务器
JeJe同学7 小时前
Docker镜像导入、容器启动
linux·运维·docker
木子n17 小时前
车载以太网与SOME/IP服务化通信实战-01.从字节到服务:SOME/IP报文解析与四通道开销账
网络·网络协议·tcp/ip·车载以太网·some/ip
Jason_zhao_MR8 小时前
Linux与实时控制如何兼得
linux·嵌入式硬件·机器人·工业控制
闲云野鹤在人间8 小时前
MySQL|从理论、安装、备份到主从复制、MHA高可用详解
linux·运维·数据库·mysql·云计算
Escalating_xu9 小时前
【C 语言】数据在内存中的存储:补码、大小端、整型陷阱与 IEEE 754 全解析
java·c语言·网络
一个风轻云淡9 小时前
GCC 和 GDB命令简单解读
java·linux·前端
爱跳舞的烤冷面9 小时前
Linux篇——网络编程
网络
H.莓飛9 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
资料库0110 小时前
Linux 8个常见运维故障排查
java·linux·运维