进程间通信

一、无名管道

1.1 Linux下进程间通信概述

1.2 无名管道通信

无名管道是内核空间实现的机制,只能用于亲缘进程间通信,无名管道的大小是64KB;

1.3 pipe函数

项目 内容
所需头文件 #include <unistd.h>
函数原型 int pipe(int pipefd[2]);
功能 创建单向数据通道(半双工通信方式)。数据只能从读端 pipefd[0] 读取,从写端 pipefd[1] 写入,方向不可逆转;数据先写入内核缓冲区,再由读进程从内核缓冲区读取。
参数 pipefd:用于存放管道读写两端的文件描述符的数组首地址
返回值(成功) 0
返回值(失败) -1,并重置错误码

1.4 无名管道

类别 特点描述
通信范围 依托具有亲缘关系的进程间的文件描述符继承特性来实现通信(如父子进程、兄弟进程)
数据传输方向 数据只能单向传输,符合半双工定义(一端读、一端写)
内核缓冲区大小 多数 Linux 系统中默认大小为 64KB
lseek 限制 不能使用 lseek 函数(管道不是普通文件),调用会返回 -1
读端存在时(写满) 写管道满则阻塞;存在约 4KB 空间时唤醒(Linux 内核为平衡效率与响应性的设计)
读端不存在时(写) 写管道会破裂,触发 SIGPIPE 信号
写端存在时(读) 读管道时若无数据,则阻塞等待
写端不存在时(读) 读管道时若无数据,则立即返回 0(非阻塞,类似读到文件结束)

二、有名管道

2.1 有名管道通信

有名管道可以用于亲缘进程通信,也可以用于非亲缘进程通信,有名管道的大小是64KB;

2.2 mkfifo函数

项目 内容
所需头文件 #include <sys/types.h> #include <sys/stat.h>
函数原型 int mkfifo(const char *pathname, mode_t mode);
功能 创建有名管道(FIFO)
参数 **pathname:**文件的路径和名字(只写名字则默认路径是当前路径)。如果管道文件已存在,则会报错(提示文件已存在) mode: 文件的权限。最终权限 = mode & ~umask
返回值(成功) 0
返回值(失败) -1,并重置错误码

2.3 unlink函数

项目 内容
所需头文件 #include <unistd.h>
函数原型 int unlink(const char *pathname);
功能 删除文件系统中的"文件名链接"(减少文件的硬链接计数,当计数归零且无进程打开时,删除文件内容)
参数 **pathname:**文件的路径和名字(只写名字则默认路径是当前路径)
返回值(成功) 0
返回值(失败) -1,并重置错误码

2.4 有名管道

类别 特点描述
数据传输方向 数据只能单向传输,符合半双工定义;若要双向通信,需创建两个管道
内核缓冲区大小 多数 Linux 系统中默认大小为 64KB
lseek 限制 不能使用 lseek 函数(管道不是普通文件),调用会返回 -1
写操作 - 读端已打开时 写入数据时会尽可能写入(受管道缓冲区大小限制);若管道已满,写操作会阻塞直到有空间
写操作 - 阻塞期间读端关闭 会产生 SIGPIPE 信号(管道破裂)
写操作 - 读端未打开(阻塞方式) 写进程在 open() 调用时会阻塞,直到有读进程打开该 FIFO
写操作 - 读端未打开(非阻塞方式) open() 调用会直接返回错误
读操作 - 写端已打开时 读取数据时,有多少读取多少;若管道为空,读操作会阻塞等待数据写入
读操作 - 写端未打开时 读进程在 open() 调用时会阻塞,直到有写进程打开该管道
读操作 - 写端曾打开但已关闭 读操作会读取剩下数据,读完后返回 0(不会阻塞,类似读到文件结束)
读操作 - 非阻塞方式打开且无写端 open() 调用会直接返回成功

三、信号

先导

信号是中断的一种软件模拟,它是基于linux内核实现的;

用户可以给进程发信号,进程可以给进程发信号,linux内核也可以给进程发信号;

对信号处理的三种方式:默认、忽略、捕捉;

3.1 常用信号

信号名 含义 默认操作
SIGKILL 用来结束进程,且不能被捕捉和忽略 终止
SIGSTOP 用于暂停进程,且不能被捕捉和忽略 暂停进程
SIGTSTP 用于暂停进程,用户可键入 SUSP 字符(通常是 Ctrl+Z)发出此信号 暂停进程
SIGCONT 让进程进入运行态 继续运行
SIGALRM 通知进程定时器时间已到 终止
SIGUSR1 / SIGUSR2 保留给用户程序使用 终止
SIGCHLD 当子进程退出时,给父进程发送该信号 忽略

3.2 signal函数

项目 内容
所需头文件 #include <signal.h>
函数原型 typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);
功能 建立信号与处理方式的关联
参数 - signum 信号的编号
参数 - handler 处理方式: • SIG_IGN:忽略 • SIG_DFL:默认 • 传递函数地址:捕捉
返回值(成功) 返回 handler 首地址
返回值(失败) 返回 SIG_ERR,并重置错误码

3.3 raise函数

项目 内容
所需头文件 #include <signal.h>
函数原型 int raise(int sig);
功能 向自身发送指定的信号
参数 - sig 要发送的信号的编号
返回值(成功) 返回 0
返回值(失败) 返回 非0

3.4 kill函数

项目 内容
所需头文件 #include <sys/types.h> #include <signal.h>
函数原型 int kill(pid_t pid, int sig);
功能 给任意进程发送信号
参数 - pid 发送信号的目标: • >0:向 pid 对应的单个进程 发送信号(最常用场景) • 0:向同进程组 的所有进程发送信号 • -1:向所有有权限操作的进程 发送信号(init进程除外,避免影响系统核心进程) • < -1:给进程组ID等于 -pid 的进程发送信号
参数 - sig 信号的编号
返回值(成功) 0
返回值(失败) -1,并重置错误码

3.5 atoi函数

项目 内容
所需头文件 #include <stdlib.h>
函数原型 int atoi(const char *nptr);
功能 将字符串转换为整数
参数 - nptr 要转换的字符串的首地址
返回值(成功) 返回转换后的整数
返回值(失败) 返回 0;如果转换后整数超出 int 范围,则行为未定义
相关推荐
Tim风声(网络工程师)18 小时前
光功率计中的红光(光衰测试设备)的使用
运维·网络
ar012318 小时前
AR电路巡检:让电力运维进入智能可视化时代
运维·人工智能·ar
island131418 小时前
【C++仿Muduo库#3】Server 服务器模块实现上
服务器·开发语言·c++
茉莉玫瑰花茶19 小时前
LangGraph 介绍
服务器·网络·数据库
mfxcyh19 小时前
如何把对象数据转化为数组
java·服务器·前端
2301_7807896620 小时前
云服务器数据会泄露吗?怎么保护云服务器的数据
运维·服务器·tcp/ip·网络安全
2301_7807896620 小时前
云服务器被黑能恢复吗?云服务器被黑的解决办法
运维·服务器·网络·安全·web安全
淘小白_TXB219620 小时前
头条百家采集改写发布软件用户使用手册
运维·服务器·头条采集·头条号采集·文章采集·头条采集软件
Web极客码21 小时前
Akismet对WordPress防垃圾评论
服务器·搜索引擎·wordpress
不怕犯错,就怕不做21 小时前
RK3562的CPU如何降频及关闭硬件编解码
linux·驱动开发·嵌入式硬件