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

9.进程间通信

9.进程间通信

      • **1. 进程间通信(IPC)概述**
      • **2. 无名管道(Pipe)**
      • **3. 有名管道(FIFO)**
      • **4. 信号通信(Signal)**
      • **5. 练习与作业**
      • **6. 信号的应用**
      • **7. 总结**


1. 进程间通信(IPC)概述

  • IPC的分类
    1. 古老的通信方式
      • 无名管道(pipe)。
      • 有名管道(fifo)。
      • 信号(signal)。
    2. IPC对象通信
      • 消息队列(较少使用)。
      • 共享内存。
      • 信号量集。
    3. Socket通信:用于网络通信。

2. 无名管道(Pipe)

  • 特性
    • 只能用于有亲缘关系的进程间通信(如父子进程)。
    • 半双工通信模式(单向通信)。
    • 数据以队列形式存储,先进先出(FIFO)。
    • 数据容量上限为64KB。
  • 使用框架
    1. 创建管道
      int pipe(int pipefd[2]);
      
      • pipefd[0]:读端。
      • pipefd[1]:写端。
    2. 读写管道
      • 读:read(pipefd[0], buffer, size);
      • 写:write(pipefd[1], buffer, size);
    3. 关闭管道
      close(pipefd[0]);
      close(pipefd[1]);
      
  • 注意事项
    • 管道的创建应在fork之前。
    • 读端关闭时,写操作会触发SIGPIPE信号。
    • 写端关闭时,读操作会返回0(表示文件结束)。

3. 有名管道(FIFO)

  • 特性
    • 可用于任意进程间通信。
    • 在文件系统中可见(通过mkfifo创建)。
    • 半双工通信模式。
  • 使用框架
    1. 创建有名管道
      int mkfifo(const char *pathname, mode_t mode);
      
    2. 打开有名管道
      int fd_read = open("./fifo", O_RDONLY);
      int fd_write = open("./fifo", O_WRONLY);
      
    3. 读写管道
      • 读:read(fd_read, buffer, size);
      • 写:write(fd_write, buffer, size);
    4. 关闭管道
      close(fd_read);
      close(fd_write);
      
    5. 卸载管道
      int unlink(const char *pathname);
      

4. 信号通信(Signal)

  • 特性
    • 异步通信方式。
    • 用于进程间发送简单的通知。
  • 信号的处理方式
    1. 默认处理:系统默认行为(如终止进程)。
    2. 忽略处理:忽略信号(如SIG_IGN)。
    3. 自定义处理:捕获信号并执行自定义函数。
  • 信号注册函数
    typedef void (*sighandler_t)(int);
    sighandler_t signal(int signum, sighandler_t handler);
    
    • handler:可以是SIG_DFL(默认)、SIG_IGN(忽略)或自定义函数。
  • 常见信号
    • SIGKILL(9):强制终止进程,不可捕获或忽略。
    • SIGSTOP(19):暂停进程,不可捕获或忽略。
    • SIGUSR1(10)和SIGUSR2(12):用户自定义信号。

5. 练习与作业

  • 练习1:设计一个多进程程序,使用无名管道在父子进程间传递任意信息(如数字、字符串)。
  • 练习2:验证管道的同步效果,测试读端关闭时写操作的行为,以及写端关闭时读操作的行为。
  • 练习3:使用有名管道实现非亲缘关系进程间的通信,支持连续发送数据并在收到quit时退出。
  • 作业1:封装有名管道的读写函数:
    int fifo_read(char *fifoname, void *s, int size);
    int fifo_write(char *fifoname, void *s, int size);
    
  • 作业2:修改有名管道通信程序,添加信号处理流程,当发送quit时,进程A发送信号,进程B收到信号后退出。

6. 信号的应用

  • 发送信号
    • kill:向指定进程发送信号。
      int kill(pid_t pid, int sig);
      
    • raise:向当前进程发送信号。
      int raise(int sig);
      
    • alarm:设置定时器,定时发送SIGALRM信号。
      unsigned int alarm(unsigned int seconds);
      
  • 信号处理
    • 自定义信号处理函数:
      void handler(int sig) {
          // 自定义处理逻辑
      }
      
    • 注册信号处理函数:
      signal(SIGUSR1, handler);
      

7. 总结

  • 无名管道:适用于有亲缘关系的进程间通信,数据容量有限。
  • 有名管道:适用于任意进程间通信,通过文件系统可见。
  • 信号通信:适用于异步通知,支持默认、忽略和自定义处理方式。

http://www.kler.cn/a/525968.html

相关文章:

  • 基于阿里云百炼大模型Sensevoice-1的语音识别与文本保存工具开发
  • 【C语言】在Windows上为可执行文件.exe添加自定义图标
  • Kafka 消费端反复 Rebalance: `Attempt to heartbeat failed since group is rebalancing`
  • RDK X5运行DeepSeek-R1-Distill-Qwen-1.5B,体验长思维链的语言大模型!
  • 【新春特辑】2025年春节技术展望:蛇年里的科技创新与趋势预测
  • 如何将 Windows 上的文件传递到 Mac 上
  • 后端token校验流程
  • Mono里运行C#脚本37—mono_compile_create_vars函数
  • Spring Boot - 数据库集成07 - 数据库连接池
  • DeepSeek 云端部署,释放无限 AI 潜力!
  • ​‌马尔可夫决策过程-笔记
  • 基于微信小程序的医院预约挂号系统设计与实现(LW+源码+讲解)
  • Python中的函数(下)
  • Node.js 的底层原理
  • 【Node.js】Koa2 整合接口文档
  • 付费进群阿泽魔改源码 跳转不卡顿
  • 剑指 Offer II 009. 乘积小于 K 的子数组
  • HarmonyOS应用开发快速入门
  • 一种用于低成本水质监测的软传感器开源方法:以硝酸盐(NO3⁻)浓度为例
  • 知识管理系统塑造企业文化与学习型组织的变革之路
  • 再写最长上升子序列(简单dp)
  • Python 列表(组织列表)
  • linux——进程树的概念和示例
  • 力扣-数组-59 螺旋矩阵Ⅱ
  • 数据结构 队列
  • 深度大数据:从数据洪流到智能决策的革命性跨越