news 2026/6/13 6:21:51

复习——IPC(进程间通信)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
复习——IPC(进程间通信)

IPC(进程间通信)完整笔记

一、IPC三大类别

1. 传统/古老通信方式
  • 无名管道(pipe):亲缘关系进程间通信

  • 有名管道(FIFO):任意进程间通信

  • 信号(signal):异步通信方式

2. IPC对象通信(System V IPC)
  • 消息队列:相对少用

  • 共享内存:最高效的通信方式

  • 信号量集:用于进程同步

3. Socket通信
  • 主要用于网络通信,也可用于本地进程通信


二、管道通信详解

2.1 管道共同特性
  1. 半双工:同一时刻只能单向传输

  2. 特殊文件

    • 不支持定位操作(lseek/fseek)

    • 使用文件IO操作(open/read/write/close)

  3. 阻塞特性

    • 读端存在,写超过64K会阻塞

    • 写端存在,读空管道会阻塞

    • 读端关闭,写端会收到SIGPIPE信号

    • 写端关闭,读端返回0(EOF)

2.2 无名管道(pipe)

创建和使用流程:

#include <unistd.h> int pipe(int pipefd[2]); // pipefd[0]:读端, pipefd[1]:写端

典型使用模式:

int fd[2]; pipe(fd); pid_t pid = fork(); if (pid > 0) { // 父进程 close(fd[0]); // 关闭读端 write(fd[1], data, size); close(fd[1]); } else if (pid == 0) { // 子进程 close(fd[1]); // 关闭写端 read(fd[0], buffer, size); close(fd[0]); }

关键结论验证:

  1. 存储方式:队列结构,先进先出(FIFO)

  2. 容量限制:实际64KB(Linux默认)

  3. 同步机制:读写端必须同时存在

  4. 方向固定:不能互换读写端

2.3 有名管道(FIFO)

创建和使用流程:

  1. 创建管道

#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode); // 例如:mkfifo("/tmp/myfifo", 0666);
  1. 打开管道(注意打开方式)

int fd_read = open("fifo_name", O_RDONLY); // 只读方式 int fd_write = open("fifo_name", O_WRONLY); // 只写方式 // 不能使用 O_RDWR 或 O_CREAT
  1. 读写操作

// 读端 read(fd_read, buffer, size); // 写端 write(fd_write, data, size);
  1. 关闭和删除

close(fd); unlink("/tmp/myfifo"); // 删除管道文件

封装函数示例:

int fifo_read(char *fifoname, void *s, int size) { int fd = open(fifoname, O_RDONLY); if (fd < 0) return -1; int ret = read(fd, s, size); close(fd); return ret; } int fifo_write(char *fifoname, void *s, int size) { int fd = open(fifoname, O_WRONLY); if (fd < 0) return -1; int ret = write(fd, s, size); close(fd); return ret; }

重要特性:

  1. 文件系统可见:可通过ls查看

  2. 任意进程访问:非亲缘关系进程可通信

  3. 阻塞特性:一端未打开时,另一端会在open时阻塞

  4. 手工操作

    bash

    复制 下载
    # 读管道 cat /tmp/myfifo # 写管道 echo "data" > /tmp/myfifo

三、信号通信(Signal)

3.1 信号特点
  • 异步通信:唯一异步的传统IPC方式

  • 中断机制:类似硬件中断

  • 信号编号:1~64,其中1~32常用

3.2 信号响应方式
类型说明不可处理信号
Term终止进程SIGKILL(9)
Ign忽略信号SIGSTOP(19)
Core终止并生成core文件
Stop暂停进程
Cont继续进程
3.3 发送信号

kill函数:

#include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig); // 成功返回0,失败返回-1

其他发送函数:

int raise(int sig); // 向自身发信号,相当于kill(getpid(), sig) unsigned int alarm(unsigned int seconds); // 定时发送SIGALRM int pause(void); // 暂停进程,等待信号
3.4 接收和处理信号

信号注册函数:

// 原形 void (*signal(int signum, void (*handler)(int)))(int); // 简化版(使用typedef) typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);

三种处理方式:

// 1. 默认处理 signal(SIGINT, SIG_DFL); // 2. 忽略处理 signal(SIGINT, SIG_IGN); // 3. 自定义处理 void my_handler(int sig) { printf("Received signal: %d\n", sig); } signal(SIGINT, my_handler);
3.5 重要结论
  1. 不可屏蔽信号

    • SIGKILL(9):强制终止,不能忽略/自定义

    • SIGSTOP(19):强制暂停,不能忽略/自定义

  2. 用户自定义信号

    • SIGUSR1(10):用户自定义信号1

    • SIGUSR2(12):用户自定义信号2

  3. 信号列表(部分常用):

    SIGHUP(1) 终端挂起 SIGINT(2) 中断(Ctrl+C) SIGQUIT(3) 退出(Ctrl+\) SIGILL(4) 非法指令 SIGTRAP(5) 跟踪陷阱 SIGABRT(6) 异常终止 SIGBUS(7) 总线错误 SIGFPE(8) 算术异常 SIGKILL(9) 强制终止 SIGUSR1(10) 用户信号1 SIGSEGV(11) 段错误 SIGUSR2(12) 用户信号2 SIGPIPE(13) 管道破裂 SIGALRM(14) 闹钟信号 SIGTERM(15) 终止信号 SIGCHLD(17) 子进程状态改变 SIGCONT(18) 继续执行 SIGSTOP(19) 暂停进程 SIGTSTP(20) 终端暂停(Ctrl+Z)

四、练习题和实验要点

4.1 无名管道实验
  1. 验证读写端:父子进程是否都有fd[0]/fd[1]

  2. 测试存储结构:验证FIFO特性

  3. 容量测试:测试管道最大容量

  4. 同步验证:测试读写阻塞情况

  5. 双向通信:使用两个管道实现双向通信

4.2 有名管道实验
  1. 进程通信:A程序发送,B程序接收

  2. 退出机制:收到"quit"双方退出

  3. 管理工具:实现fifo_tool创建/删除管道

  4. 封装函数:实现fifo_read/fifo_write

4.3 信号实验
  1. 自定义kill程序:模拟系统kill命令

  2. 信号响应测试:测试所有32个信号响应

  3. 自定义处理:实现信号自定义处理函数

五、实用技巧和注意事项

5.1 管道使用技巧
  1. 双向通信:使用两个管道(一个读一个写)

  2. 进程同步:利用管道的阻塞特性

  3. 错误处理:检查read/write返回值

  4. 资源清理:及时关闭管道文件描述符

5.2 信号使用技巧
  1. 信号重入:信号处理函数应为可重入函数

  2. 信号屏蔽:使用sigprocmask屏蔽不需要的信号

  3. 信号队列:实时信号可排队,标准信号可能丢失

  4. 竞态条件:注意信号处理时的竞态问题

5.3 调试技巧
  1. 管道调试

    strace -e trace=read,write,pipe,close ./program
  2. 信号调试

    strace -e trace=signal,kill ./program
  3. 查看进程信号

    ps -eo pid,cmd | grep program kill -l # 查看信号列表
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 19:15:19

改进狼群算法与粒子群优化在机械臂路径规划与轨迹优化中的应用

110-改进狼群算法的机械臂路径规划代码&#xff0c;粒子群对机械臂关节进行轨迹优化 改进点&#xff1a; ① 自适应步长、 ② 莱纬飞行、 ③ 自适应召唤等改进 一共三个核心代码&#xff0c;构成完整的运动学路径规划轨迹优化对比实验&#xff1a; [1]图1 a、b、c、d为蚁群、遗…

作者头像 李华
网站建设 2026/6/13 3:34:17

第二章:状态、动态与时间的可计算表达

– 第二章&#xff1a;状态、动态与时间的可计算表达 2.1 时间并不是变量&#xff0c;而是问题本身 在第一章中&#xff0c;我们将连续世界抽象为特征、存在与场景&#xff0c;使世界首次具备了可操作性。 然而&#xff0c;这仍然遗漏了一个关键维度——时间。 时间与空间不同。…

作者头像 李华
网站建设 2026/6/11 19:12:06

cesium126,240308,Ce for Ue 加载ArcGIS WMTS Map:

&#xff08;246&#xff09; 这个网站&#xff0c;包含了在线地图&#xff0c; 但似乎是国外的网站&#xff0c;很慢&#xff0c; 用 cesium 的 WMTs 覆层进行加载 &#xff1a; Cesium for Unreal加载ArcGIS WMTS Map ArcGIS WMTS Map几个地图示例: https://map.geoq.cn/arcg…

作者头像 李华
网站建设 2026/6/10 15:01:34

Windows系统文件dmenrollengine.dll损坏或丢失 下载修复

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

作者头像 李华