news 2026/6/26 0:45:18

OS学习之路——进程间通信

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OS学习之路——进程间通信

OS学习之路——进程间通信

    • 前言
    • 为什么需要进程间通信
    • 什么是进程间通信
    • 进程间通信
      • 数据拷贝类型
      • 基于共享内存
      • 基于信号

前言

  • 之前我们学习了进程的相关话题,这次我们来学习和进程相关的一个话题——进程间通信

为什么需要进程间通信

  • 假设你想从你的朋友那里获取一些信息,你就会想在微信或者现实中去询问他,反之亦然。你可以把你和你的朋友想象成两个进程,此时你们为了获取信息就需要和对方通信。这就是一个进程间通信的例子
  • 还有在网络世界中,我们从浏览器中获取信息,首先需要从浏览器发请求,浏览器也是一个进程,服务器收到我们的请求后,他会有专门的程序处理,这也是一个进程。这也是一个进程间通信的例子
  • 还有许多的例子,在计算机的世界中也是这样,同一台机器上的一个进程可能也需要另一个进程提供的信息完成工作

什么是进程间通信

  • 通过前面的文章,我们知道进程实际上是计算机中正在运行程序的一个代表,一个进程内部的pcb包含了这个程序的程序计数器、打开的文件、地址空间等信息。一个进程不可能自己完成所有的 工作,总会有一些进程完成工作需要配合外部进程
  • 进程间通信顾名思义发生在进程间进行通信的过程,那么又有哪些形式呢?
    • 基于数据拷贝:管道,消息队列,套接字
    • 基于共享内存:共享内存
    • 基于信号:信号,信号量
  • 下面我们来逐个介绍上述内容

进程间通信

数据拷贝类型

  • 管道

    • 匿名管道:只可以发生在有亲缘关系的进程(父子进程),依赖于pipe函数,一个大小为2的数组,1代表写端,0代表读端,可以使用readwrite函数进行读写数据。
    • 原理:pipe调用成功后,内核会创建一个管道对象,这里包含了缓冲区 、读写指针、等待队列等,并返回两个文件描述符,当前进程以及和当前进程有亲缘关系的进程都可以继承这两个描述符,这时就可以使用这两个描述符通过readwrite函数进行读写了,匿名管道是单向的,读写方式在程序编写是就固定了,确定哪方读/写后就不可以改变
    intfd[2];pipe(fd);if(fork()==0){write(fd[1],"hello",5);}else{charbuf[10];read(fd[0],buf,5);}
    • 命名管道:可以发生在无亲缘关系的进程,可以使用mkfifo(const char *pathname, mode_t mode)函数或者使用mkfifo filename创建一个管道文件,管道文件使用p进行标识
    • 原理:在内核创建一个缓冲区,表现形式为一个管道文件,这个管道文件仍然可以使用系统调用进行openreadwrite,但是其内部的数据并不会持久化到磁盘内,但是仍然可以使用ls -i命令查询到其inode号,且不能使用cat或者>>>查看文件或者写入内容。需要注意的是不能仅以读或者写方式打开这个文件,在只有一种方式访问文件的时候,在另一种方式未到来前当前操作是阻塞的,读者可以打开两个终端,一个使用cat命令查看文件,一个使用echo "hello" >> pipefile,在没有第二步前第一个终端是一直阻塞的
    • 命名管道是半双工的,双方都可以担任读/写的角色,但是同一时刻数据只能向一端流动
    • 套接字:可以发生在任何进程,可以跨主机,使用socket函数创建一个套接字描述符,通信双方依赖套接字处理读写事件
    • 原理:数据会存储在内核的socket缓冲区,当要读取数据时,会从内核缓冲区拷贝到用户自定义的缓冲区,当发送数据时,从用户的缓冲区拷贝到内核的socket缓冲区准备发送。
    • 套接字是全双工的,数据可以同时双向流动

基于共享内存

  • 共享内存:使用于进程间通信,上面讲的几个至少要经过两次拷贝,共享内存可以减少至0次,也叫零拷贝
  • 原理:使用shm_open创建一个共享内存, 使用mmap进行映射,当需要读取或写入内容时,直接对这块内存操作即可
  • 共享内存是全双工的,但是因为任何知道这个共享内存存在的进程都可以读取其内容,所以需要注意使用同步机制保护数据的完整性
#include<sys/mman.h>#include<fcntl.h>#include<unistd.h>#include<string.h>intmain(){constchar*name="/myshm";constsize_t SIZE=4096;// 1. 创建共享内存对象(读写,如果存在则打开,模式0644)intfd=shm_open(name,O_CREAT|O_RDWR,0644);// 2. 调整大小ftruncate(fd,SIZE);// 3. 映射到进程地址空间char*ptr=mmap(0,SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);// 4. 写入数据strcpy(ptr,"Hello from writer");// 5. 解除映射munmap(ptr,SIZE);// 6. 关闭描述符(数据仍然保留在共享内存中)close(fd);// 注意:不要 shm_unlink,否则读进程无法打开return0;}

基于信号

  • 信号
    • 实际上是内核向某个进程发送了中断通知,然后进程响应中断做出的答复,使用signal注册信号以及信号的处理方式,这个方法是异步的,不需要缓冲区
    #include<signal.h>#include<iostream>voidhandler(intsig){std::cout<<"received signal\n";}intmain(){signal(SIGUSR1,handler);while(1){}}
  • 信号量:本质上是一个原子的计数器,可以用来控制资源访问和实现进程间同步。当需要获取资源时,自减计数器,归还资源时,自增计数器
  • 下面这个程序得到的结果是990001
#include<iostream>#include<sys/semaphore.h>#include<thread>intmain(){volatilestd::size_t idx=1;// int num = 1;sem_t x;sem_init(&x,0,1);std::threadth1([&](){for(inti=0;i<1000000;++i){sem_wait(&x);++idx;sem_post(&x);}});std::threadth2([&](){for(inti=0;i<10000;++i){sem_wait(&x);--idx;sem_post(&x);}});th1.join();th2.join();sem_destroy(&x);std::cout<<idx<<std::endl;return0;}

通过这些介绍,你对进程间通信是否有了一个全新的认识?如果觉得写的还不错的话,欢迎点赞关注,如果有不对的地方,欢迎批评指正。

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

如何通过Lean 4开源生态系统突破数学验证与编程的边界

如何通过Lean 4开源生态系统突破数学验证与编程的边界 【免费下载链接】lean4 Lean 4 programming language and theorem prover 项目地址: https://gitcode.com/GitHub_Trending/le/lean4 当你面对复杂的数学定理验证或需要构建类型安全的算法时&#xff0c;Lean 4正在…

作者头像 李华
网站建设 2026/6/26 0:44:33

YALMIP终极指南:如何在MATLAB中快速构建和求解优化模型

YALMIP终极指南&#xff1a;如何在MATLAB中快速构建和求解优化模型 【免费下载链接】YALMIP MATLAB toolbox for optimization modeling 项目地址: https://gitcode.com/gh_mirrors/ya/YALMIP YALMIP是一个功能强大的MATLAB优化建模工具箱&#xff0c;它将复杂的数学优化…

作者头像 李华
网站建设 2026/6/13 14:43:37

二叉树遍历(前序、中序、后序)递归与迭代

二叉树遍历是数据结构中的经典问题&#xff0c;前序、中序、后序三种遍历方式通过递归或迭代实现&#xff0c;展现了算法设计的巧妙之处。无论是理解递归的简洁性&#xff0c;还是掌握迭代的栈模拟技巧&#xff0c;都能帮助开发者深入理解树结构操作。本文将带你探索不同遍历方…

作者头像 李华
网站建设 2026/4/13 11:09:13

储能系统数据采集与监控一体化融合架构设计:基于边缘微服务并发本地 Web 监控与 MQTT 上云的实现

摘要&#xff1a; 针对新能源现场部署“IPC 网关”双系统带来的实施复杂、硬件成本高、数据一致性差的挑战&#xff0c;本文分享一种在边缘算力终端中利用微服务机制实现底层采集与上层本地 Web 监控并发的高阶架构&#xff0c;这种数据采集与监控一体化设计极大缩短了现场交付…

作者头像 李华
网站建设 2026/4/13 11:08:14

ROS新手必看:解决‘rospack找不到包’报错的三种常见原因与排查步骤

ROS环境配置实战&#xff1a;从报错到精通的包管理全解析 当你第一次在终端看到[rospack] Error: package xxx not found的红色报错时&#xff0c;那种手足无措的感觉我至今记忆犹新。ROS的包管理系统就像一座精心设计的迷宫——当你掌握了它的规则&#xff0c;一切都会变得井…

作者头像 李华