05进程间通信-学习笔记

进程间通信(IPC)

概念

进程信技术简称IPC,可以利用此技木让多个进程相传建消数据,有大量的进程间通信方案

  • pipe 匿名管道
  • fifo 命名管简单理解,管道文件是一个指向内核管道缓冲区的指针,所有向管道文件读写的操作,都会重定向到内核管道中道
  • Posix 消息队列
  • System 消息队列
  • Signal 信号
  • Socket 套接字
  • MMAP 文件映射

进程有虚拟地址空间,进程间通信在虚拟地址的哪一层实现的?

绝大多数进程间通信是在内核层完成的, 因为内核层内存共享

pipe 匿名管道

为了便于开发者使用管道可以使用pipe函数创建管道,创建成功后会生成两个文件描述符,分别指向管道的读端fds[0]和写端fds[1]。匿名管道只能再有亲缘关系的进程之间使用

管道的原理

两个进程公用一个管道,实现通信

管道的特点
  1. 是一种传输介质,可以传输数据
  2. 管道传输具有方向性
  3. 管道具备存储能力,虽然不能持久存储,只能暂存
缺点

匿名管道只能在有亲缘关系的进程间的通信

使用管道

创建
pipe(int fds[2]);

注意:管道创建要在 创建子进程之前完成, 避免子进程创建管道


使用
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <pthread.h>
#include <signal.h>

#define MSG "HI"

int main()
{
    pid_t pid;
    int fds[2];

    pipe(fds);
    pid = fork();
    // 父进程写,子进程读
    if (pid > 0)
    {

        close(fds[0]); // 父进程关闭读功能,文件描述符-1
        printf("parent pid %d alive..\n", getpid());
        sleep(5);
        write(fds[1], MSG, strlen(MSG)); // 父进程写入信息
        printf("parent pid %d send msg success..\n", getpid());
        close(fds[1]); // 父进程使用完成写的功能,关闭写功能,文件描述符-1
    }
    else if (pid == 0)
    {
        close(fds[1]); // 子进程关闭写功能,文件描述符-1
        char buffer[1024];
        bzero(buffer, sizeof(buffer));
        read(fds[0], buffer, sizeof(buffer)); // 子进程读管道中的内容

        printf("child read msg %s \n", buffer);
        close(fds[0]); // 子进程使用完成读的功能,关闭写功能,文件描述符-
        exit(0);
    }
    else
    {
        perror("FORK CALL FAILED");
        exit(0);
    }
}

回收
  1. 每个指向管道的描述符都是一个引用计数,如果引用计数为0,系统自动释放管道空间,否则管道一直存在于内核层
  2. 管道使用时要确定通信方向,父写子读,子写父读,父子进程将不用的描述符关闭 关闭不用的
  3. pipe_fd使用完毕要close 引用计数-1 用完要关闭
  4. shutdown可以直接将引用计数清0

工作方式

单工 : 确定通信方向, 非读即写, 不可变更

半双工/可调节单工: 非读即写,但是不同时刻可以调节读写

双工:可以同时读写


匿名管道使用时的四种特殊情况

这四种情况具有普遍意义

  1. 管道的读写两端存在但是写端未向管道内写数据,读端读取完管道数据后如果管道为null,再次读阻塞
  2. 管道读写两端存在,但是读端未读取管道数据,写端写满管道后,再次写阻塞
  3. 管道写端关闭,读端读取管道剩余内容后,再次读读到0
  4. 管道读端关闭,写端向管道写数据,系统会发送SIGPIPE信号,杀死写端进程,读端关闭的情况下不允许写端访问管道

在一个C/S模型中,客户端发送了一条请求消息之后客户端异常关闭,服务端回复结果时异常关闭,服务端异常关闭原因?

(SIGPIPE信号)send(sockfd , buffer, size , MSG NOSIGNAL)

FIFO 命名管道

是一个内核缓冲区,为环形队列结构, 大小为4k,命名管道可以解决无关联进程间的通信

特点

管道通信与传统的文件传输不同,读取文件内容并不会除文件内容,但是管道是队列结构,出队的数据会从管道消失

可以持久化存储的磁盘文件并不适合作为传输介质

原理

简单理解,管道文件是一个指向内核管道缓冲区的指针,所有向管道文件读写的操作,都会重定向到内核管道中

使用

mkfifo pname #命令创建管道文件

mkfifo(char * pname,0664) #函数创建管道文件

管道文件的访问是要凑齐两种权限的 即使 RDWR,如果某个进程以一种权限打开管道文件, open函数会立即阻塞,等待另一种权限。即使只有一个进程 只要满足读写权限,就可以成功打开管道了

命名管道的两种特殊情况

一个读端中存在多个读序列,阻塞读只对第一个读序列有效,其他读序列被设置为非阻塞

1693832281723.png

管道的原子访问与非原子访问

1693832341789.png

判定是原子传输或是非原子,取决于用户发送数据包大小,如果数据包<=管道大小, 则是原子传输,如果数据包>管道大小(即4K) 就是非原子传输

非原子访问,最大化的利用容器空间, 只有容器满时才会限制写端,读写效率传输效率高,但是数据会被多次拆分,会对读端造成一些麻烦,读端要验证数据包完整性后才可以使用

mmap文件映射

功能

是一种内存映射文件的技术,它允许将文件映射到进程的虚拟内存空间,使得文件的内容可以像访问内存一样被读取和写入。

1、基本使用

头文件

#include <sys/mman.h>

函数原型、参数、返回值

void * ptr = mmap(NULL , size , PROT READIPROT WRITE , int how , int fd , 0);

参数

mmap%E5%8F%82%E6%95%B0.drawio.png

映射方式

共享映射 MAP_SHARED,共享映射有 Sync同步机制
私有映射 MAP_PRIVATE

原理

多进程间利用 MAP_SHARED的Sync同步机制可以实现共享映射实现进程通信

1688305464094.png

返回值

成功返回映射内存地址ptr
失败返回MAP_FAILED关键字

回收

munmap(ptr,size); //释放映射内存

使用细节

  1. 确定消息结构体大小
  2. 根据消息结构体大小,确定映射文件大小。大小为消息结构体的倍数
  3. 拓展空文件,使用截断方式,将映射文件拓展成一个指定的大小ftruncate(fd,sizeof(msg_t)*4096)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/mman.h>

int main()
{
    int fd;
    fd = open("map_file", O_RDWR);
    int size = lseek(fd, 0, SEEK_END);
    int *ptr = NULL;
    if ((ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED)
    {
        perror("mmap call failed");
        exit(0);
    }
    close(fd);
    sleep(10);
    ptr[0] = 0x34333231;
    munmap(ptr, size);
    return 0;
}

2、大数据文件处理,切割处理

1689385376866.png

最后一个参数,控制偏移量
映射偏移量必须是4k的整数倍,因为内存分页一页为4k。

1689385534267.png

3、零拷贝,减少拷贝开销

零拷贝并不是指完全节省拷贝或切换开销,而是尽可能较少

1689386098791.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/244951.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

人机交互——自然语言理解

人机交互中的自然语言理解是人机交互的核心&#xff0c;它是指用自然语言&#xff08;例如中文、英文等&#xff09;进行交流&#xff0c;使计算机能理解和运用人类社会的自然语言&#xff0c;实现人机之间的自然语言通信。 自然语言理解在人工智能领域中有着非常重要的地位&a…

计算机网络(三)

&#xff08;十一&#xff09;路由算法 A、路由算法分类 动态路由和静态路由 静态路由&#xff1a;人工配制&#xff0c;路由信息更新慢&#xff0c;优先级高。这种在实际网络中要投入成本大&#xff0c;准确但是可行性弱。 动态路由&#xff1a;路由更新快&#xff0c;自动…

【操作系统导论】内存篇——分页

引入 采用 「分段」 的方式&#xff0c;将空间切成 不同长度的分片&#xff0c;会出现 碎片化 问题&#xff0c;随着时间推移&#xff0c;分配内存会越来越困难。 因此&#xff0c;值得考虑「分页」的方法&#xff1a; 将空间分割成 固定长度的分片 &#xff1b; 将物理内存…

中医电子处方管理系统软件,中医配方模板一键生成软件操作教程

一、前言&#xff1a; 在中医开电子处方时&#xff0c;如果能够使用配方模板功能&#xff0c;则可以节省很多时间。使用配方模板一键导入&#xff0c;几秒即可完成开单。 下面就以佳易王电子处方管理系统软件V17.1版本为例说明&#xff0c;其他版本可以参考&#xff0c;软件下…

场景的组织及渲染(一)

在OSG 中存在两棵树&#xff0c;即场景树和渲染树。场景树是一棵由 Node组成的树,这些Node可能是矩阵变换、状态切换或真正的可绘制对象&#xff0c;它反映了场景的空间结构&#xff0c;也反映了对象的状态。本章重点介绍场景树&#xff0c;在第 5章将会对渲染树作详细的介绍。…

GoWin FPGA, GPIO--- startup2

一个Bank只能用一个电压&#xff0c;假如同一个Bank&#xff0c;在引脚里设置不同的电压&#xff0c;编译不过。 解释说明 2. 错误引脚限制 以上编译设置会导致编译错误。

Docker | 发布镜像到镜像仓库

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏:Docker系列 ✨特色专栏: MySQL学习 🥭本文内容:Docker | 发布镜像到镜像仓库 📚个人知识库: [Leo知识库]https://gaoziman.gitee.io/bl…

std::vector

这里主要介绍下reserce/resize、push_back/emplace_back、shrink_to_fit/clear等接口&#xff1b; 1. reserve and resize C的vector对象可以通过reserve方法来设置vector对象的容量&#xff0c;通过resize方法来改变vector对象的大小。reserve所设置的容量指的是vector容器中可…

0基础学习VR全景平台篇第127篇:什么是VR全景/720全景漫游?

“全景”作为一种表现宽阔视野的手法&#xff0c;在很久之前就得到了普遍的认同。北宋年间&#xff0c;由张择端绘制的《清明上河图》就是一幅著名的全景画。摄影术出现后&#xff0c;全景摄影也随之而生。 到今天&#xff0c;全景拍摄不再被专业摄影师所独享&#xff0c;广大…

云计算与AI融合:Amazon Connect开创客户服务智能时代

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 在亚马逊云科技 re:Invent 2023 大会上&#xff0c;Amazon Connect…

[AutoSar]状态管理(四)单核BswM(二)流程、配置、 代码

目录 关键词平台说明一、BswM的模式处理流程图二、stand state handling三、配置、代码、状态转移3.1 initial -> wakeup   3.2 WakeUp -> Run3.3 Run -> PostRun &#xff08;first step&#xff09;3.4 Run -> PostRun &#xff08;second step&#xff09;3.5…

Python安装报错: This environment is externally managed

error: externally-managed-environment This environment is externally managed ╰─> To install Python packages system-wide, try apt installpython3-xyz, where xyz is the package you are trying toinstall.这个错误信息表示当前Python环境是由系统外部管理的&…

基于Docker-Compose实现ELK+Kafka搭建分布式日志采集系统

ELKKafka搭建日志采集系统 ELK概述搭建与配置docker-compose.yml配置日志采集规则启动服务 模拟发送日志消息日志发送队列日志切面配置application.yaml发送日志消息 Kibana的使用创建索引模式Discovery搜索数据可视化数据 ELKRabbitMQ发送日志消息配置日志采集规则 ELK概述 E…

Java IO 流详解

Java IO 流详解 1 .Java IO概念 Java IO&#xff1a;即 Java 输入 / 输出系统。 Java 的 IO 模型设计非常优秀&#xff0c;它使用 Decorator (装饰者)模式&#xff0c;按功能划分 Stream &#xff0c;您可以动态装配 这些 Stream &#xff0c;以便获得您需要的功能。 Stream &…

20 Redis进阶 - 运维监控

1、理解Redis监控 Redis运维和监控的意义不言而喻&#xff0c;可以以下三个方面入手 1.首先是Redis自身提供了哪些状态信息&#xff0c;以及有哪些常见的命令可以获取Redis的监控信息; 2.一些常见的UI工具可以可视化的监控Redis; 3.理解Redis的监控体系;2、Redis自身状态及命…

【Java反射详解】

Java反射详解 &#x1f38a;专栏【Java】 &#x1f354;喜欢的诗句&#xff1a;关山难越&#xff0c;谁悲失路之人。 萍水相逢&#xff0c;尽是他乡之客。 &#x1f386;音乐分享【Counting Stars 】 欢迎并且感谢大家指出问题&#x1f970; 1.什么是反射 所谓的反射就是java…

365锦鲤助手 砍价小程序源码 流量主引流裂变

源码介绍 修改版365锦鲤 助手&#xff0c; 砍价小程序源码 流量主引流裂变 拼多多商品快速丰富产品内容满足广大用户需求&#xff1b;流量矩阵让流量都进你的圈子飞起来&#xff1b;长期盈利、项目稳定 1.后台安装微擎 2安装应用 后台打包上传

PPINN Parareal physics-informed neural network for time-dependent PDEs

论文阅读&#xff1a;PPINN Parareal physics-informed neural network for time-dependent PDEs PPINN Parareal physics-informed neural network for time-dependent PDEs简介方法PPINN加速分析 实验确定性常微分方程随机常微分方程Burgers 方程扩散反应方程 总结 PPINN Par…

Npm安装vue3报错(node:25436) MaxListenersExceededWarning:

运行命令安装vue3时 npm create vuelatest 报了错误(node:25436) MaxListenersExceededWarning: (忘记截报错的图了&#xff0c;后面还有一大串英文) 搞了很久发现是网络的原因&#xff0c;我没有修改镜像地址&#xff0c;导致访问很慢&#xff0c;于是去npmmirror 镜像站 …

字符雨canvas

整体思路&#xff1a; 确定好字符雨的具体字符是什么&#xff0c;需要多少行多少列这里是写死的其实也可以用循环加随机的方式生成不一样的字符雨&#xff0c;行列也可以读一下宽度然后做一下出发算一下也行首先得有一张画布搞起&#xff0c;然后循环列数去绘画字符定时器循环…