当前位置: 首页 > news >正文

复习——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 # 查看信号列表
http://www.jsqmd.com/news/119804/

相关文章:

  • 5 款 AI 写论文哪个好?深度实测后,这款 “学术实力派” 藏不住了!
  • 写论文软件哪个好?虎贲等考 AI:毕业论文创作的 “全能通关神器”
  • 降重 + 去 AIGC 痕迹双 buff!虎贲等考 AI:让论文原创性 “无可挑剔”
  • 8个AI论文工具,自考本科轻松搞定写作难题!
  • 10 个AI写作工具,助你轻松搞定继续教育论文!
  • 期刊投稿屡投屡拒?虎贲等考 AI:让学术成果精准叩开核心期刊大门
  • 虎贲等考 AI:AI 赋能学术创作,全流程论文辅助工具革新登场
  • 【开题答辩全过程】以 基于VUE的爱心捐赠物资信息管理系统为例,包含答辩的问题和答案
  • [Android] 高德地图V9.1车机版 (2025 年测试版)
  • 课程论文还在熬夜凑字数?虎贲等考 AI:让学术写作高效又拿分
  • 某能源AI应用架构师亲述:用成熟度模型推动AI节能落地
  • 问卷设计还在 “手动凑题”?虎贲等考 AI:30 分钟搞定专业级调研问卷,告别无效提问
  • [Windows] 自动小说生成工具AI_NovelGenerator_V1.4.4
  • 9 款 AI 写论文哪个好?实测对比后,这款全流程神器成学术党首选! 毕业论文写作季,AI 写作工具已成学子 “救命稻草”。市面上百度智能云千帆大模型、科大讯
  • win32创建内存映射文件
  • 解析 React 的 ‘Object Inlining’ 优化:如何减少虚拟 DOM 创建时的临时对象分配?
  • Bootstrap3 全局控制秘籍:前端老手都在用的隐藏技巧大公开
  • Prometheus 核心概念 及 安装部署
  • 如何诊断 React 中的“闭包过时”:利用静态扫描工具自动发现 `useEffect` 的依赖缺失
  • 第二章:状态、动态与时间的可计算表达
  • 第三章:因果的形成——从动态到方法
  • 改进狼群算法与粒子群优化在机械臂路径规划与轨迹优化中的应用
  • 解析 ‘External Store Tearing’:为什么并发渲染中,从非 React 管理的 Store 读取数据会出错?
  • 并发模式下的内存压力:如果同时启动 100 个 Transition 任务,React 堆内存会爆炸吗?
  • 删除Windows系统并安装Ubuntu系统
  • 什么是 ‘State Snapshot’?解析 React 如何在多次渲染间保持闭包状态的一致性
  • 百度AI架构师亲授:Agentic智能体在医疗领域的落地(附诊断案例)
  • COMSOL Multiphysics 负压抽采瓦斯数值模拟探索
  • C++进阶:(十六)从裸指针到智能指针,C++ 内存管理的 “自动驾驶” 进化之路 - 指南
  • LeetCode 122. 买卖股票的最佳时机 II - 推荐贪心