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

IPC进程间通信详解

匿名管道

匿名管道的本质就是内存里一块缓冲区

pipe(int fd[2] );

创建一个struct pipe_inode_info,创建两个struct file,struct file的void* private_data指向struct pipe_inode_info,第一个file绑定读端,第二个file绑定写端,最后将两个file的文件描述符按照读写的顺序返回给int fd[2]数组


struct file {
    struct path f_path;          // 文件路径(含dentry和挂载点)
    void *private_data;          // 实际指向 pipe_inode_info(管道专属数据)
};


struct path {
    struct dentry *dentry;       // 目录项(指向管道文件的dentry)
};


struct dentry {
    struct inode *d_inode;       // 关联的inode(指向管道inode)
};


struct inode {
    struct pipe_inode_info *i_pipe;  // 指向管道数据结构
    const struct file_operations *i_fop; // 操作函数集(指向fifo_fops)
};


struct pipe_inode_info {
    struct mutex mutex;          // 互斥锁(保护管道操作)
    unsigned int head;           // 写入位置
    unsigned int tail;           // 读取位置
    struct pipe_buffer *bufs;    // 环形缓冲区数组(存储数据页)
};

1.struct file里的file_operations也是用的inode里面的file_operations,这样就可以实现不同文件类型就有不同的回调函数系统调用,

  • 管道:pipefifo_fops(实现 pipe_read()/pipe_write())。
  • 普通文件:ext4_file_operations(实现磁盘读写)。
  • Socket:socket_file_ops(实现网络通信)。

这是一切皆文件的设计思路

2.匿名管道需要进程fork创建子进程,因为匿名管道没有路径无法被其他进程看到,只能通过继承的方式使子进程继承父进程的文件描述符表

3.匿名管道半双工的,只能支持一个方向的通信,双方进程要商量谁保留读,谁保留写。如果要用管道实现全双工,则需要两个管道。为什么要设计半双工呢?因为管道通信的阻塞和唤醒都是由内核来做的,半双工是为了简化设计

4.管道的读写是通过系统调用的,所以数据会被先拷贝进内核缓冲区,再拷贝进管道缓冲区

命名管道

命令行:mkfifo filename

系统调用:int  mkfifo(const char* filename, mode_t mode)

mkfifo的行为

struct dentry {
    struct inode *d_inode;       // 关联的inode(指向管道inode)

    struct dentry *d_parent; // 父目录的 dentry

    struct qstr d_name; // 文件名(含哈希值)
};


struct inode {
    struct pipe_inode_info *i_pipe;  // 指向管道数据结构
    const struct file_operations *i_fop; // 操作函数集(指向fifo_fops)
};


struct pipe_inode_info {
    struct mutex mutex;          // 互斥锁(保护管道操作)
    unsigned int head;           // 写入位置
    unsigned int tail;           // 读取位置
    struct pipe_buffer *bufs;    // 环形缓冲区数组(存储数据页)
};

创建对应dentry结构,并创建struct  inode和pipe_inode_info,pipe_inode_info里有pipe_buffer缓冲区。有了dentry结构后加入dentry树,然后给父目录里加文件名inode映射,这样命名管道就有了路径

open命名管道的行为

open会根据路径去dentry树里查找fifo,找到之后创建struct file,其void* private_data指向dentry里struct inode里面的pipe_inode_info,struct file里的file_operations也指向struct inode里的file_operations,然后返回文件描述符

1.匿名管道同样有dentry结构,但没有加入dentry树里面,所以无法走路径那一套来创建文件描述符,只能靠继承来传递文件描述符,然后再利用系统调用来实现通信。而命名管道将dengtry结构加入dentry树可以走路径这一套来创建struct file,然后用系统调用来通信,并且路径这一套使通信不再局限在血缘关系进程之间而是所有进程之间

2.命名管道也是半双工的,只能支持一个方向的通信,open方式表明该struct file绑定的读端还是写端。如果要用命名管道实现全双工,则也需要两个管道。为什么要设计半双工呢?因为管道通信的阻塞和唤醒都是由内核来做的,半双工是为了简化设计

3.命名管道的读写也是通过系统调用的,所以数据会被先拷贝进内核缓冲区,再拷贝进管道缓冲区

system V共享内存

共享内存是最快的进程间通信方式,和管道一样,共享内存也是内存里的一块缓冲区,那为什么共享内存比管道快呢?

1.共享内存直接靠页表将物理内存映射到虚拟空间,用虚拟地址来直接操作物理内存,而管道是通过系统调用来操作物理内存,这其中还有一个先将数据拷贝到内核缓冲区的过程

2.管道通信是通过内核系统调用实现的,因此有阻塞唤醒这些进程同步机制,而共享内存不加保护,所以会更快

System V 共享内存的使用流程​

​(1) 创建/获取共享内存段​

#include <sys/shm.h>

key_t key = ftok("/some/file", 'A');  // 根据路径和项目ID生成唯一 key
int shmid = shmget(key, size, IPC_CREAT | 0666);  // 创建/获取共享内存

  • shmget 参数​​:
    • key:唯一标识符(ftok 生成或手动指定)。
    • size:共享内存大小(字节)。
    • flagsIPC_CREAT(不存在则创建) + 权限(如 0666)。

​(2) 映射到进程地址空间​

void *shmaddr = shmat(shmid, NULL, 0); // 映射到当前进程

  • shmat 参数​​:
    • shmidshmget 返回的 ID。
    • addr:通常设为 NULL(由内核选择映射地址)。
    • shmflg0(可读写),或 SHM_RDONLY(只读)。

​(3) 使用共享内存​

// 进程 A 写入数据
sprintf((char *)shmaddr, "Hello, Shared Memory!");

// 进程 B 读取数据
printf("Data: %s\n", (char *)shmaddr);

  • ​直接通过指针操作​​,无需 read/write

​(4) 解除映射​

shmdt(shmaddr); // 解除映射(不删除共享内存)

​(5) 删除共享内存(

shmctl(shmid, IPC_RMID, NULL); // 标记为删除(最后一个进程 detach 后真正释放)

相关文章:

  • 索引下探(Index Condition Pushdown,简称ICP)
  • MCP与AI模型的多语言支持:让人工智能更懂世界
  • 数据库6——综合实验-水果商店进阶一
  • Axure酒店管理系统原型
  • Python入门手册:Python中的数据结构类型
  • Gartner《Optimize GenAI Strategy for 4 Key ConsumerMindsets》学习心得
  • 力扣:《螺旋矩阵》系列题目
  • 豪越科技:消防应急装备智能仓储管理新变革
  • 深入理解设计模式:工厂模式、单例模式
  • 解析 Flask 上下文机制:请求上下文、应用上下文
  • HTTP协议初认识、速了解
  • 机器学习中的多GPU训练模式
  • WebXR 虚拟现实开发
  • Python爬虫(37)Python爬虫深度实践:Splash渲染引擎与BrowserMob Proxy网络监控协同作战
  • 使用 Go 语言实现完整且轻量级高性能的 MQTT Broker
  • vue3使用七牛云上传文件
  • MySQL主从同步原理
  • 快速失败(fail-fast)和安全失败(fail-safe)的区别
  • 传统医疗系统文档集中标准化存储和AI智能化更新路径分析
  • 爬虫知识之IP代理
  • 网站选项按钮/哈尔滨百度搜索排名优化
  • 浙江省住房和城乡建设部网站/合肥关键词排名技巧
  • 攸县住房和城乡规划建设局网站/贴吧友情链接在哪
  • 电子商务官方网站建设/b站推广
  • 推荐广州微信网站建设/网站流量统计系统
  • 如何制作网站板块/哪个平台可以免费推广