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, 用完之后别忘了恢复默认

相关推荐
云计算练习生9 小时前
什么是系统调用?为什么程序访问硬件必须经过它
linux·windows·操作系统·系统调用·操作系统原理
boxiansheng1639 小时前
408计算机网络
网络·计算机网络·智能路由器
玄芯散人10 小时前
【筑基·059】Linux命令行入门:工程师的操作系统
linux·操作系统·命令行
闲云野鹤在人间10 小时前
docker 入门 | 第5章 网络详解
网络·docker·架构·华为云·php
半仙白桑10 小时前
内核篇第二讲:Linux exec 函数族详解
linux·linux驱动
AR-26710-10 小时前
Linux Day7——建组/用户、umask、Python脚本
linux·python
orange....10 小时前
VMware 双网卡配置:宿主机切换网络时 Ubuntu 固定 IP 访问方案
网络·ubuntu·网络安全
吴声子夜歌10 小时前
Shell编程实例——内务及管理任务(一)
linux·运维·shell
byte轻骑兵10 小时前
【BlueZ 】input 模块:蓝牙鼠标/键盘等输入设备的基础适配逻辑
linux·人工智能·bluez·电脑蓝牙·嵌入式蓝牙
yi碗汤园11 小时前
MQTT消息队列遥测传输协议
网络·网络协议·unity