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

10.共享内存 信号量集 消息队列

10.共享内存 信号量集 消息队列

      • **1. IPC对象操作通用框架**
      • **2. 共享内存(Shared Memory)**
      • **3. 信号量集(Semaphore)**
      • **4. 消息队列(Message Queue)**
      • **5. 练习与作业**
      • **6. 总结**


1. IPC对象操作通用框架

  • 操作流程
    1. 生成唯一键值(ftok
      key_t ftok(const char *pathname, int proj_id);
      
      • 功能:通过路径和项目ID生成唯一键值。
      • 参数:
        • pathname:文件路径。
        • proj_id:项目ID(通常为ASCII字符)。
      • 返回值:成功返回键值,失败返回-1
    2. 申请IPC对象
      • 共享内存:shmget
      • 信号量集:semget
      • 消息队列:msgget
    3. 操作IPC对象
      • 共享内存:shmatshmdt
      • 信号量集:semop
      • 消息队列:msgsndmsgrcv
    4. 删除IPC对象
      • 共享内存:shmctl
      • 信号量集:semctl
      • 消息队列:msgctl

2. 共享内存(Shared Memory)

  • 特性
    • 效率最高的进程间通信方式。
    • 多个进程可以共享同一块内存区域。
  • 操作流程
    1. 申请共享内存
      int shmget(key_t key, size_t size, int shmflg);
      
      • 功能:申请共享内存。
      • 参数:
        • key:唯一键值。
        • size:共享内存大小。
        • shmflg:权限标志(如IPC_CREAT|0666)。
      • 返回值:成功返回共享内存ID,失败返回-1
    2. 映射共享内存
      void *shmat(int shmid, const void *shmaddr, int shmflg);
      
      • 功能:将共享内存映射到进程地址空间。
      • 参数:
        • shmid:共享内存ID。
        • shmaddr:映射地址(通常为NULL,由系统分配)。
        • shmflg:映射标志(如0表示读写,SHM_RDONLY表示只读)。
      • 返回值:成功返回映射地址,失败返回(void*)-1
    3. 读写共享内存
      • 使用memcpystrcpy等函数直接操作映射地址。
    4. 撤销映射
      int shmdt(const void *shmaddr);
      
      • 功能:断开共享内存映射。
      • 参数:shmaddr:映射地址。
      • 返回值:成功返回0,失败返回-1
    5. 删除共享内存
      int shmctl(int shmid, int cmd, struct shmid_ds *buf);
      
      • 功能:删除共享内存。
      • 参数:
        • shmid:共享内存ID。
        • cmd:命令(如IPC_RMID表示删除)。
        • buf:共享内存信息结构体(通常为NULL)。
      • 返回值:成功返回0,失败返回-1

3. 信号量集(Semaphore)

  • 特性
    • 用于解决共享内存的临界资源访问问题。
    • 通过P(sem_wait)和V(sem_post)操作实现同步。
  • 操作流程
    1. 申请信号量集
      int semget(key_t key, int nsems, int semflg);
      
      • 功能:申请信号量集。
      • 参数:
        • key:唯一键值。
        • nsems:信号量数量。
        • semflg:权限标志(如IPC_CREAT|0666)。
      • 返回值:成功返回信号量集ID,失败返回-1
    2. 初始化信号量
      • 使用semctl初始化信号量值。
    3. P/V操作
      int semop(int semid, struct sembuf *sops, unsigned nsops);
      
      • 功能:执行P/V操作。
      • 参数:
        • semid:信号量集ID。
        • sops:操作结构体数组。
        • nsops:操作数量。
      • 返回值:成功返回0,失败返回-1
    4. 删除信号量集
      int semctl(int semid, int semnum, int cmd, ...);
      
      • 功能:删除信号量集。
      • 参数:
        • semid:信号量集ID。
        • semnum:信号量编号。
        • cmd:命令(如IPC_RMID表示删除)。
      • 返回值:成功返回0,失败返回-1

4. 消息队列(Message Queue)

  • 特性
    • 用于进程间传递消息。
    • 消息以队列形式存储,先进先出(FIFO)。
  • 操作流程
    1. 申请消息队列
      int msgget(key_t key, int msgflg);
      
      • 功能:申请消息队列。
      • 参数:
        • key:唯一键值。
        • msgflg:权限标志(如IPC_CREAT|0666)。
      • 返回值:成功返回消息队列ID,失败返回-1
    2. 发送消息
      int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
      
      • 功能:发送消息。
      • 参数:
        • msqid:消息队列ID。
        • msgp:消息结构体指针。
        • msgsz:消息大小。
        • msgflg:发送标志(如0表示阻塞)。
      • 返回值:成功返回0,失败返回-1
    3. 接收消息
      ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
      
      • 功能:接收消息。
      • 参数:
        • msqid:消息队列ID。
        • msgp:消息结构体指针。
        • msgsz:消息大小。
        • msgtyp:消息类型。
        • msgflg:接收标志(如0表示阻塞)。
      • 返回值:成功返回消息大小,失败返回-1
    4. 删除消息队列
      int msgctl(int msqid, int cmd, struct msqid_ds *buf);
      
      • 功能:删除消息队列。
      • 参数:
        • msqid:消息队列ID。
        • cmd:命令(如IPC_RMID表示删除)。
        • buf:消息队列信息结构体(通常为NULL)。
      • 返回值:成功返回0,失败返回-1

5. 练习与作业

  • 练习1:使用共享内存完成两个进程间的通信,共享一个数字。
  • 练习2:设计两个进程,进程1获取用户输入并写入共享内存,进程2读取共享内存并打印输出,遇到exit时退出。
  • 作业1:封装信号量的P/V操作函数:
    int my_sem_wait(int id, int sem);
    int my_sem_post(int id, int sem);
    
  • 作业2:使用信号量集解决共享内存的临界资源访问问题。

6. 总结

  • 共享内存:效率最高的IPC方式,适合大数据量传输。
  • 信号量集:用于解决共享内存的同步问题。
  • 消息队列:适合进程间传递结构化消息。

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

相关文章:

  • 【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
  • qt内部的特殊技巧【QT】
  • Python NumPy(7):连接数组、分割数组、数组元素的添加与删除
  • 大数据相关职位介绍之二(数据治理,数据库管理员, 数据资产管理师,数据质量专员)
  • C++ 中用于控制输出格式的操纵符——setw 、setfill、setprecision、fixed
  • 【Linux权限】—— 于虚拟殿堂,轻拨密钥启华章
  • 【2】阿里面试题整理
  • windows怎么查看进程运行时的参数?
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.22 形状操控者:转置与轴交换的奥秘
  • (●ˇ∀ˇ●)思维导图计划~~~
  • 进阶数据结构——高精度运算
  • 探索性测试与自动化测试的结合
  • android 音视频系列引导
  • Python3 【集合】项目实战:3 个新颖的学习案例
  • 【笑着写算法系列】二分查找
  • 在 WSL2 中重启 Ubuntu 实例
  • 特殊Token区域与共享区域
  • 分享|借鉴传统操作系统中分层内存系统的理念(虚拟上下文管理技术)提升LLMs在长上下文中的表现
  • LINUX部署微服务项目步骤
  • C++:多继承习题5
  • 文件(c语言文件流)
  • AI时序预测: iTransformer算法代码深度解析
  • UE学习日志#15 C++笔记#1 基础复习
  • 无线通信与人工智能技术与发展年度总结
  • MYSQL 商城系统设计 商品数据表的设计 商品 商品类别 商品选项卡 多表查询
  • Kafka 压缩算法详细介绍