操作系统 --- 进程通信 IPC Inter Process Communication

2023-10-26

为什么需要进程通信

  • 不同的进程之间需要交换大量的数据

进程通信的方法

pipeline

什么是pipeline

  • pipe是一块内存,被视为"virual file" (实际不是file 不在文件系统中, 而是存在于内存之中的一块缓冲区)
  • pipe是单向通信,pipe的一端连接输出进程(read end),一端连接输入进程(write end),
  • read end和write end是两个file descriptor(数据类型是int)
  • 一般会创建一个int数组: fd[2], fd[0]代表read end, fd[1]代表write end
  • 主要用于父进程和子进程之间,或者有共同祖先的两个进程, 因为需要父进程创建pipe
  • 进程结束后,pipe被自动释放

shell中的pipe

  • 在shell中 “ | ” 代表pipeline
  • 可以将 “|" 前面的commond处理完的数据传给后面的command
    在这里插入图片描述

创建过程

  • 一个进程创建完pipe之后,write end和read end都在同一进程里
  • 然后这个进程fork一个子进程,此时子进程也同时拥有write end和read end
  • 父进程关掉其中一端,子进程关掉另外一端,实现单向通信
    在这里插入图片描述

pipe的同步机制

  • 管道自带同步互斥机制:
    管道的内核实现:fs/pipe.c ,主要通过内核的锁以及等待队列等机制实现
  • 管道的write操作会阻塞进程
    当内存缓冲区已满或被读进程锁定,会阻塞write操作
    当所有数据被写入管道时write操作才会结束
  • 管道的read操作会阻塞进程
    当读进程被阻塞时会形成等待队列,并让等待队列进入休眠
    当所有子进程关闭管道的写入端的操作时会停止阻塞
    父进程的写入端操作关闭时,父进程的读操作会停止阻塞
  • 当所有读取端和写入端都关闭后,管道才能被销毁
    ————————————————
    版权声明:本文为CSDN博主「z_stand」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/Z_Stand/article/details/100806493

实现pipe通信 — system call: pipe()

父进程和子进程之间

  • 创建一个进程A,然后创建pipe
  • 进程A fork一个进程B
  • 进程A关闭write end
  • 进程B关闭read end

实现两个子进程之间的pipe通信

  • 创建一个进程A,并创建pipe
  • 进程A fork一个子进程B, 子进程B关闭write end
  • 进程A 关闭read end,然后fork子进程C,此时子进程C只有read
  • 进程A关闭write end,和pipe脱离关系
  • 子进程B, C实现了单向通信
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>

int main(int argc, char *argv[]) {
    int fds[2];
    char buff[60];
    int count;
    int i;
    pipe(fds);
    
    int pid1 = fork();
    if (pid1 == 0) {
	printf("Child process A %d: Read from the pipe \n", getpid());
	//child A close write, and has the read
        close(fds[1]);
	while ((count=read(fds[0], buff, 60)) > 0) {
	    for(i=0; i<count; i++) {
	        write(1, buff+i, 1);
		write(1, " ", 1);
	    }
	    printf("\n");
	}
	close(fds[0]);
	exit(0);
    }
    else {
        //parent close read
    	close(fds[0]);
	int pid2 = fork();
	if (pid2 == 0) {
	    //child B has the write since read is already closed by its parent
	    printf("Child process B %d: write to the pipe \n", getpid());
	    for(i=1; i<argc; i++) {
	        write(fds[1], argv[i], strlen(argv[i]));
	    }
	    exit(0);
	    
	}
	else {  
	    //parent close write
	    close(fds[1]);
	    wait(NULL);
        printf("This is the parent process %d\n", getpid());
	}
    }
    exit(0);
}

pipe的缺点

  • 没有名称,只能支持有共同祖先的进程之间的通信, 不能支持任意两个进程的通信
  • 进程结束之后pipe也被释放

FIFO (Named Pipe)

什么是FIFO or Named Pipe

  • 为了解决pipe的缺点,出现了named pipe
  • named pipe一般是一个真正的文件,存在于文件系统中,只要操作系统不关闭就一直存在
  • FIFO file就是named pipe的实现
  • 所有进程可以对FIFO file进行读写操作,就像读写正常文件一样
  • FIFO是多向通信

创建一个FIFO file — system call: mkfifo()

  • int mkfifo(const char *filename,mode_t mode);
    在这里插入图片描述

FIFO的同步机制

  • FIFO总是处于阻塞状态。
  • 当FIFO打开时设置了读权限,则读进程将一直“阻塞”,一直到其他进程打开该FIFO并且向管道中写入数据。这个阻塞动作反过来也是成立的,
  • 如果一个进程打开一个管道写入数据,当没有进程从管道中读取数据的时候,写管道的操作也是阻塞的,直到已经写入的数据被读出后,才能进行写入操作。
  • 如果不希望在进行命名管道操作的时候发生阻塞,可以在open()调用中使用 O_NONBLOCK标志,以关闭默认的阻塞动作。
    ————————————————
    版权声明:本文为CSDN博主「Change_Improve」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/Change_Improve/article/details/98731329

shared memory

什么是shared memory

  • 多个进程可以访问同一块内存(正常情况下,进程不能互相访问对方的内存空间)

shared memory原理

  • 在Linux中,每个进程都有属于自己的进程控制块(PCB)和地址空间(Addr Space),并且都有一个与之对应的页表,负责将进程的虚拟地址与物理地址进行映射,通过内存管理单元(MMU)进行管理。两个不同的虚拟地址通过页表映射到物理空间的同一区域,它们所指向的这块区域即共享内存。
    ————————————————
    原文链接:https://blog.csdn.net/ypt523/article/details/79958188
    在这里插入图片描述

shared memory的问题

  • 下图中的读写操作不是原子操作(转换成汇编语言之后不是原子操作), 有可能在写入时读取或者读取时写入
  • 需要使用信号量(semaphore) 来实现同步与互斥
    在这里插入图片描述

使用shared memory

  • The ftok function creates a identifier to be used with the IPC functions (semget, shmget, msgget)
  • ftok token is valid across the system, so that two or more independent processes have the same access to IPC recourses (shared memory, message queue)
    在这里插入图片描述

message queue

  • message queue是存在内核中的一个链表
  • 通过message queue indentifier辨别
  • 通过system call操作
  • 比shared memory要慢

在这里插入图片描述

socket

To be continued

Windows和Linux采用的进程通信的方法

Windows

  • memory mapping
  • pipelines
  • messages

Linux

  • pipe (pipe),
  • FIFO (named pipe),
  • socket (socket),
  • SHM (Shared memory),
  • MSG queue (Message queue),
  • mmap (file map).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

操作系统 --- 进程通信 IPC Inter Process Communication 的相关文章

  • 找不到包“gdk-pixbuf-2.0”

    我正在尝试在 Amazon Linux 发行版实例上构建 librsvg 我已经通过 yum 安装了大部分依赖项 其中一些在实例上启用的默认 yum 存储库中不可用 因此必须从头开始构建它们 我已经走了很远 但还停留在最后一点 跑步时sud
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu
  • 适用于 Linux 的轻量级 IDE [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • linux下无法创建僵尸进程

    嗯 我有一个奇怪的问题 我无法在我的项目中创建僵尸进程 但我可以在其他文件中创建僵尸进程 有简单的说明 int main if fork 0 printf Some instructions n else sleep 10 wait 0 r
  • 调用 printf 系统子例程在汇编代码中输出整数错误[重复]

    这个问题在这里已经有答案了 来回 在windows7控制台窗口中运行gcc s2 asm 然后生成一个exe文件 运行a exe 然后崩溃 为什么 s2 asm 代码由以下源代码生成 int m m 1 iprint m s2 asm请参考
  • 如何为 Linux 桌面条目文件指定带有相对路径的图标?

    对于我的一个 Linux 应用程序 我有应用程序二进制文件 一个 launcher sh 脚本 针对 LD LIBRARY PATH 和一个 desktop 文件 所有这些都位于同一文件夹中 我想使用图标的相对路径而不是绝对路径 我试过了
  • 我们真的应该使用 Chef 来管理 sudoers 文件吗?

    这是我的问题 我担心如果 Chef 破坏了 sudoers 文件中的某些内容 可能是 Chef 用户错误地使用了说明书 那么服务器将完全无法访问 我讨厌我们完全失去客户的生产服务器 因为我们弄乱了 sudoers 文件并且无法再通过 ssh
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 在 Linux 上以编程方式设置 DNS 名称服务器

    我希望能够通过我的 C C 程序为 Linux 上的 DNS 名称服务器添加 IP 地址 我在一个带有只读 etc resolv conf 的嵌入式平台上 这意味着我不能简单地将 nameserver xxx xxx xxx xxx 行添加
  • 尽管 if 语句,Visual Studio 仍尝试包含 Linux 标头

    我正在尝试创建一个强大的头文件 无需更改即可在 Windows 和 Linux 上进行编译 为此 我的包含内容中有一个 if 语句 如下所示 if defined WINDOWS include
  • 如何获取 (Linux) 机器的 IP 地址?

    这个问题和之前问的几乎一样如何获取本地计算机的IP地址 https stackoverflow com questions 122208 get the ip address of local computer 问题 但是我需要找到一个的I
  • 使用包管理器时如何管理 Perl 模块?

    A 最近的问题 https stackoverflow com questions 397817 unable to find perl modules in intrepid ibex ubuntu这让我开始思考 在我尝试过的大多数 Li
  • Bash - 在与当前终端分开的另一个终端中启动命令的新实例

    我有一个简单的 bash 脚本 test sh 设置如下 bin bash args if args 0 check capture then watch n 1 ls lag home user capture0 watch n 1 ls
  • 如何在 Linux 中使用 C 语言使用共享内存

    我的一个项目有点问题 我一直在试图找到一个有据可查的使用共享内存的例子fork 但没有成功 基本上情况是 当用户启动程序时 我需要在共享内存中存储两个值 当前路径这是一个char and a 文件名这也是char 根据命令参数 启动一个新进
  • Intel 上的 gcc 中的 _mm_pause 用法

    我参考过这个网页 https software intel com en us articles benefitting power and performance sleep loops https software intel com
  • 如何使用Android获取Linux内核的版本?

    如何在 Android 应用程序中获取 Linux 内核的版本 不是 100 确定 但我认为调用 uname r 需要 root 访问权限 无论如何 有一种不太肮脏的方法可以做到这一点 那就是 System getProperty os v
  • 使用 gdb 调试 Linux 内核模块

    我想知道 API 在内核模块 中返回什么 从几种形式可以知道 这并不是那么简单 我们需要加载符号表来调试内核模块 所以我所做的就是 1 尝试找到内核模块的 text bss和 data段地址 2 在 gdb 中使用 add symbol f
  • Apache 访问 Linux 中的 NTFS 链接文件夹

    在 Debian jessie 中使用 Apache2 PHP 当我想在 Apache 的文档文件夹 var www 中创建一个新的小节时 我只需创建一个指向我的 php 文件所在的外部文件夹的链接 然后只需更改该文件夹的所有者和权限文件夹
  • 我什么时候应该编写 Linux 内核模块?

    有些人出于某种原因想要将 Linux 中的代码从用户空间移动到内核空间 很多时候 原因似乎是代码应该具有特别高的优先级 或者只是 内核空间更快 这对我来说似乎很奇怪 我什么时候应该考虑编写内核模块 有一套标准吗 我怎样才能激励将代码保存在
  • ansible unarchive 模块如何查找 tar 二进制文件?

    我正在尝试执行一个 ansible 剧本 该剧本的任务是利用unarchive模块 因为我是在 OSX 上执行此操作 所以我需要使用它gnu tar 而不是bsd tar通常与 OSX 一起提供 因为BSD tar 不受官方支持 https

随机推荐

  • 零撸项目-Star Network注册流程

    大家好 我是面具少年 本次主要讲解 Star Network注册流程 Star Network 本项目仅零撸 不建议投资 内容仅供参考 具有支付功能的社交 DeFi 去中心化金融 网络 是未来的去中心化金融平台 具有交换借贷 钱包和支付功能
  • list_del使用错误,如果摘链后还有挂链,请使用list_del_init。否则引发血案!!!

    rt
  • 开发下载成套的icon图标的知识

    下载成体系的icon图标 再也不用到处找成套的图标了 iconfont 阿里巴巴矢量图标库 选择完之后选择点赞靠前的一个 进入之后 ctrl f 输入需要的图标 会自动检索当前页面的所有图标 然后快速定位 选择你喜欢的下载就好了 拜拜
  • Mac安装VM虚拟机

    一 所需文件 VMware Fusion Pro CentOS 7 x86 64 Minimal 2003 iso 二 下载 去vm官网下载vm安装包 下载完成后进行安装 三 安装 如下图所示 双击安装包 进行安装 把下载好的centos拖
  • 【单元测试】Google Test(GTest)和Google Mock(GMock)--编辑中

    目录 Gtest简介 局限性 入门例子 还可以打印信息 进阶 测试我们函数的API ASSERT 和EXPECT TEST TEST F TEST P的区别 ASSERT 和EXPECT 说明 简单的测试例子 Test Fixtures 为
  • 网页前端开发

    内容 智能表单样式扩展 max width 表示最大宽度 text align 字体居中 某些属性样式直接写到form里面不行 需要写在style 里面 CSS入门 CSS入门 CSS简介 CSS指的是Cascading Style She
  • MySQL主键约束(PRIMARY KEY ,PK)

    MySQL主键约束 PRIMARY KEY PK 在数据库中使用过程中 如果 想将某个字段作为唯一标识 标记所有内容时 则可以使用PK 约束进行设置 即PK约束在创建数据库表时为某些字段加上 PRIMARY KEY 约束条件 则该字段可以唯
  • 一张表看清哪些企业属于阿里大厂版图

    一张表看清哪些企业属于阿里大厂版图 百胜餐饮集团已经宣布与春华资本集团及蚂蚁金融服务集团达成协议 二者共同向百胜中国投资4 60亿美元 该项投资将与百胜餐饮集团与百胜中国的分拆同步进行 蚂蚁金服将帮助百胜中国为旗下品牌提供移动支付服务 包括
  • RuntimeError: cuda runtime error (11) : invalid argument at /pytorch/aten/src/THC/THCGeneral.cpp

    RuntimeError cuda runtime error 11 invalid argument at pytorch aten src THC THCGeneral cpp cuda9 0 torch0 4 解决办法 在demo p
  • 【Unity】Mod形式的Dll及AssetBundle外部加载插件

    综述 本插件利用Mono cecil静态注入模块 BepInEx包含的一个dll 实现在Unity游戏预加载 PreLoader 阶段的Dll修补工作 用以达到通过同版本Unity创建AssetBundle时候 无法打包脚本导致的游戏运行过
  • 解决mysql数据库依靠web前端存入数据navicat出现中文乱码,而使用sqlyog正常

    因为之前学习数据库就习惯使用navicat 在后边学习java web时就一直使用他 但是却发现从前端添加进来的数据 中文变成了问号 但是前端从这里取出 也还是正常 就只是在这里边看是问号 我之前也查询了很多方法 那些人都说是mysql数据
  • 提高网站搜索排名

    提升网站排名的方式 一种是充钱开挂 百度的三流医院广告 另一种就是通过SEO Search Engine Optimization 优化技术来实现 本文仅考虑后者 一 搜索引擎的排名机制 搜索引擎如何发现并收录新网站 搜索引擎的背后是一套不
  • 最强虚拟ip服务器,虚拟ip服务器

    虚拟ip服务器 内容精选 换一换 一 前言因为云上的原因 基于Keepalived虚拟出来的ip是没办法是通信的 所以我们可以在Keepalived上虚拟的ip再去申请一个绑定服务器的操作 为之后使用HA Keepalived打个基础 在华
  • Linux终端默认配色方案

    1 类Unix终端CLI颜色指代的文件类型 比如蓝色是目录 绿色是可执行程序 类Unix一切皆文件 文件共分7种类型 7种类型的文件分别由不同的颜色指代 1 普通文件类型 ls l 带 的类型 一般为终端默认的字体颜色 其中 可执行程序 二
  • 数字金字塔

    输入n值 打印下列形状的金字塔 其中n代表金字塔的层数 Input 输入只有一个正整数n Output 打印金字塔图形 其中每个数字之间有一个空格 Sample Input 3 Sample Output 1 1 2 1 1 2 3 2 1
  • 无序数组排序并得到最大间隔

    问题描述 给定一个无序整型数组 求将其排好序后 并得出相邻两个数之间的最大差值 例如 1 3 2 5 7 4 13 排序后 1 2 3 4 5 7 13 那么最大间隔是6 这个问题大部分人会想到先排序后遍历的解法 但是这个问题要求的时间复杂
  • CSS——float浮动属性

    float浮动 div1 width 100px height 100px background red float left div2 width 300px height 300px background blue float righ
  • Unity界面插件NGUI基础教程

    一 创建你的界面 1 创建一个新场景 2 选择并删除场景里的MainCamera 3 在NGUI菜单下选择Create a New UI 会打开UI创建向导 4 在创建向导中你能更改UI的基本参数 现在我们选Default layer 点击
  • Python工业项目实战 05:数仓事实层DWB层构建

    知识点01 课程回顾 项目中有哪些主题域 服务域 工单主题 安装主题 客户域 客户事主题 仓储域 物料主题 运营域 工时主题 市场域 工单主题 项目中有哪些核心维度 时间维度 地区维度 油站维度 服务站点维度 组织机构维度 物流维度 仓库维
  • 操作系统 --- 进程通信 IPC Inter Process Communication

    操作系统 进程通信 IPC Inter Process Communication 为什么需要进程通信 进程通信的方法 pipeline 什么是pipeline shell中的pipe 创建过程 pipe的同步机制 实现pipe通信 sys