【Linux】进程间通信——进程间通信的介绍和分类、管道、匿名管道、命名管道、匿名管道与命名管道的区别

文章目录

  • 进程间通信
    • 1.进程间通信的介绍
      • 1.1目的和发展
    • 2.进程间通信分类
    • 3.管道
      • 3.1匿名管道
        • 3.1.1匿名管道的原理(文件角度)
        • 3.1.2匿名管道的原理(内核角度)
        • 3.1.3管道读写规则
        • 3.1.4管道特点
      • 3.2命名管道
        • 3.2.1创建命名管道
        • 3.2.2命名管道的打开规则
    • 4.命名管道实现server&client通信

进程间通信

1.进程间通信的介绍

  进程间通信(IPC,Interprocess communication)是一组编程接口,让程序员能够协调不同的进程,使之能在一个操作系统里同时运行,并相互传递、交换信息。这使得一个程序能够在同一时间里处理许多用户的要求。因为即使只有一个用户发出要求,也可能导致一个操作系统中多个进程的产生。进程间通信可以发生在同一台机器上的不同进程间,也可以发生在不同机器上的进程间。
  

1.1目的和发展

  目的:

  (1)数据传输:一个进程需要将它的数据发送给另一个进程。

  (2)资源共享:多个进程之间共享同样的资源。

  (3)通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。

  (4)进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。
  
  发展:

  管道 -> System V进程间通信 -> POSIX进程间通信。
  

2.进程间通信分类

  管道:匿名管道、命名管道

  System V IPC:System V 消息队列、System V 共享内存、System V 信号量

  POSIX IPC:消息队列、共享内存、信号量、互斥量、条件变量、读写锁
  

3.管道

  管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”。
在这里插入图片描述
  

3.1匿名管道

  匿名管道的原理:

  匿名管道的原理是使用pipe函数创建管道,并在父进程中得到两个文件描述符,一个用于从管道读数据,另一个用于向管道写数据。 子进程在创建时会自动继承这两个文件描述符,从而可以实现父子进程间的数据交换。

#include <unistd.h>//功能:创建一无名管道//原型
int pipe(int fd[2]);//参数
//fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
//返回值:成功返回0,失败返回错误代码

在这里插入图片描述

//例子:从键盘读取数据,写入管道,读取管道,写到屏幕
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main( void )
{int fds[2];char buf[100];int len;if ( pipe(fds) == -1 )perror("make pipe"),exit(1);// read from stdinwhile ( fgets(buf, 100, stdin) ) {len = strlen(buf);// write into pipeif ( write(fds[1], buf, len) != len ){perror("write to pipe");break;}memset(buf, 0x00, sizeof(buf));// read from pipeif ( (len=read(fds[0], buf, 100)) == -1 ) {perror("read from pipe");break;}// write to stdoutif ( write(1, buf, len) != len ) {perror("write to stdout");break;}}
}

  

3.1.1匿名管道的原理(文件角度)

  匿名管道的原理从文件角度来说,是利用内存中共享的一段缓冲区,以文件的方式对缓冲区实现。但因为该文件只存在于内存中,没有唯一命名,所以称为匿名管道。

  具体来说,父进程创建管道文件描述符,然后通过fork创建子进程。子进程继承了父进程的文件描述符,这样父子进程就可以通过这个文件描述符进行通信。 由于管道是半双工方式,数据传输的方向是单向的,所以如果需要进行双向通信,需要创建两个管道。

在这里插入图片描述

在这里插入图片描述

  

3.1.2匿名管道的原理(内核角度)

  从内核角度来说,匿名管道的原理是利用内核缓冲区作为伪文件,这个缓冲区由读端和写端两部分组成,对应两个文件描述符。数据从写端流入,从读端流出。

  匿名管道的内部实现方式是队列,而且是环形队列。这种队列的特性是先进先出,即一端入队,另一端出队,即只能从一端写入,另一端读出。缓冲区的大小默认是4k字节,但会根据实际情况做适当调整。

  由于用队列实现,数据只能读取一次,不能重复读取。另外,匿名管道是半双工方式,数据传输的方向是单向的。此外,匿名管道只适用于有血缘关系的进程,如父子进程、兄弟进程等。

在这里插入图片描述

这也符合了Linux的一切皆文件的思想

  
  父进程tast_struct中有指向file_struct的指针 *file,其中files_struct是一个struct file *fd_array[],这个array的数组中指向了各种的文件。同时创建子进程,子进程是父进程的一份拷贝,所以此时父进程指向的文件,子进程也同样会指向该文件,进程间通信的前提完成:让不同的文件看到同一份资源。

  
在这里插入图片描述
  

  接着,我们可以进行不同进程间的通信了,如果我们想要先让子进程写入,父进程读取。则我们可以在父进程和子进程所指的同一个文件中,进行不同的操作:让子进程在文件缓冲区中写入数据,让父进程在同样的文件缓冲区中读取数据。即可完成通过使用管道的通信操作(所以管道也是文件)。

在这里插入图片描述
  

3.1.3管道读写规则

  (1)当没有数据可读时
  O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来到为止。
  O_NONBLOCK enable:read调用返回-1,errno值为EAGAIN。

  (2)当管道满的时候
  O_NONBLOCK disable: write调用阻塞,直到有进程读走数据。
  O_NONBLOCK enable:调用返回-1,errno值为EAGAIN。

  (3)如果所有管道写端对应的文件描述符被关闭, 则read返回0。

  (4)如果所有管道读端对应的文件描述符被关闭, 则write操作会产生信号SIGPIPE,进而可能导致write进程退出。

  (5)当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。

  (6)当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。

  

3.1.4管道特点

  (1)只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信; 通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道。

  (2)管道提供流式服务

  (3)一般而言,进程退出,管道释放,所以管道的生命周期随进程

  (4)一般而言,内核会对管道操作进行同步与互斥

  (5)管道是半双工的,数据只能向一个方向流动; 需要双方通信时,需要建立起两个管道。

在这里插入图片描述
  

3.2命名管道

  命名管道的介绍:

  Linux命名管道是一种特殊的文件类型,它允许不具有亲缘关系的进程之间进行通信。命名管道存在于文件系统中,但同时具有管道的优点,可以用于进程间通信。进程通过操作命名管道文件进行数据交换。

  命名管道的创建可以使用命令行工具(如mkfifo命令)或者在编程语言中的调用系统调用接口(如mkfifo函数)来创建。 创建好命名管道之后,可以使用open()和read/write()函数来读取和写入数据。

  在数据传输方面,命名管道的数据传输不会写入磁盘,而是在内存中进行传递。命名管道允许多个进程通过使用相同的管道名称进行通信,而不仅仅是两个进程之间的通信。与普通管道一样,命名管道中的数据也是临时存储在内存中的。

  

3.2.1创建命名管道

  命名管道可以从命令行上创建:

$ mkfifo filename

  
  命名管道也可以从程序里创建,相关函数有:

int mkfifo(const char *filename,mode_t mode);

  
  创建命名管道:

int main(int argc, char *argv[])
{mkfifo("p2", 0644);return 0;
}

  
  匿名管道与命名管道的区别:

  (1)匿名管道由pipe函数创建并打开。

  (2)命名管道由mkfifo函数创建,打开用open。

  (3)FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。

  

3.2.2命名管道的打开规则

  (1)如果当前打开操作是为读而打开FIFO时
  O_NONBLOCK disable:阻塞直到有相应进程为写而打开该FIFO。
  O_NONBLOCK enable:立刻返回成功。

  (2)如果当前打开操作是为写而打开FIFO时
  O_NONBLOCK disable:阻塞直到有相应进程为读而打开该FIFO。
  O_NONBLOCK enable:立刻返回失败,错误码为ENXIO。

  

4.命名管道实现server&client通信

测试实现:

在这里插入图片描述
  

comm.hpp

#pragma once#include<iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<cerrno>
#include<string>
#include <unistd.h>
#include <fcntl.h>#define FIFO_FILE "./myfifo"
#define MODE 0664enum{FIFO_CREATE_ERR=1,FIFO_DELETE_ERR=2,FIFO_OPEN_ERR=3
};

  
Makefile

.PHONY:all
all:server client
server:server.ccg++ -o $@ $^ -std=c++11
client:client.ccg++ -o $@ $^ -std=c++11
.PHONY:clean
clean:rm -f client server myfifo

  
server.cc

//#include<iostream>
#include"comm.hpp"using namespace std;//管理管道文件
int main()
{//创建信道int n=mkfifo(FIFO_FILE,MODE);if(n==-1){perror("mkfifo");exit(FIFO_CREATE_ERR);}//sleep(5);//打开信道int fd=open(FIFO_FILE,O_RDONLY);if(fd<0){perror("open");exit(FIFO_OPEN_ERR);}cout<<"server open file done"<<endl;//开始信道while(true){char buffer[1024]={0};int x=read(fd,buffer,sizeof(buffer));if(x>0){buffer[x]=0;cout<<"client say#"<<buffer<<endl;}else if(x==0){cout<<"clinet quit,me too!\n"<<endl;break;} else break;}close(fd);int m=unlink(FIFO_FILE);if(m==-1){perror("unlink");exit(FIFO_DELETE_ERR);}return 0;
}

  
client.cc

#include<iostream>
#include"comm.hpp"using namespace std;int main()
{int fd=open(FIFO_FILE,O_WRONLY);if(fd<0){perror("open");exit(FIFO_OPEN_ERR);}string line;while(true){cout<<"Please Enter@";//cin>>line;getline(cin,line);write(fd,line.c_str(),line.size());}close(fd);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谈思生物医疗直播 | 利用类器官模型研究肺的发育与稳态

类器官是一种三维细胞培养物&#xff0c;其在细胞类型&#xff0c;空间结构及生理功能上能够模拟对应器官&#xff0c;从而提供一个高度生理相关的系统。自2009年小肠类器官首次建立至今&#xff0c;类器官研究已经延伸到多个组织系统&#xff0c;并成为当下生命科学领域最热门…

美创获IDC数据库安全市场代表厂商推荐,一路引领数据库安全

近日&#xff0c;全球领先的IT市场研究和咨询公司IDC发布《IDC Persepctive&#xff1a;中国数据库安全市场洞察&#xff0c;2023》报告。 凭借多年的技术积累和丰富的产品体系与行业实践&#xff0c;美创科技获「代表厂商」推荐&#xff0c;再次彰显专业领先能力&#xff01; …

Mybatis一级缓存和二级缓存原理剖析与源码详解

Mybatis一级缓存和二级缓存原理剖析与源码详解 在本篇文章中&#xff0c;将结合示例与源码&#xff0c;对MyBatis中的一级缓存和二级缓存进行说明。 MyBatis版本&#xff1a;3.5.2 文章目录 Mybatis一级缓存和二级缓存原理剖析与源码详解⼀级缓存场景一场景二⼀级缓存原理探究…

部署项目时常用的 Linux 命令

目录 1 前言2 SSH登录命令3 SCP传输命令4 CP拷贝命令5 MV移动命令6 TAR解压命令7 DU查看文件夹/文件大小8 TAIL查看日志9 NOHUP后台运行10 结语 1 前言 在应用部署过程中&#xff0c;Linux命令是必不可少的工具。它们能够帮助我们管理文件、连接服务器、拷贝文件、查看日志以及…

vite项目配置vite.config.ts在打包过程中去除日志

在生产环境上&#xff0c;务必要将日志清除干净&#xff0c;其因有二&#xff0c;在webgis系统中&#xff0c;有很多几何数据&#xff0c;体积大、数量多&#xff0c;很容易引起系统卡顿&#xff1b;清除log后&#xff0c;系统看着舒服&#xff0c;协同开发有很多无聊的日志&am…

一款非常优秀的项目管理工具:进度猫(推荐)

在项目管理中&#xff0c;一个好的工具可以极大地提高效率。 进度猫是一款非常优秀的项目管理工具。它具有非常强大的功能&#xff0c;可以帮助团队更好地管理项目进度。 通过可视化的方式&#xff0c;将项目进度、任务分配、需求变更等全面呈现给团队成员&#xff0c;让团队…

需求分析BSA法

&#x1f449;BSA法&#xff08;Basic–Satisfier–Attractor&#xff09;是对客户需求进行优先级划分的需求分析方法。该模型体现了需求满足度和客户满意度之间的非线性关系。BSA法将客户需求分为3种类型&#xff0c;分别是基本型需求、满意型需求和兴奋型需求。下面将对每种需…

ABB机 器 人 操 作 培 训

目 录 1 培训手册介绍 ---------------------------------------------2 2 系统安全与环境保护 ---------------------------------------------3 3 机器人综述 ---------------------------------------------5 4 机器人示教 --------------------------------------------12…

FSCTF2023-Reverse方向题解WP。学习贴

文章目录 [FSCTF 2023]signin[FSCTF 2023]MINE SWEEPER[FSCTF 2023]Xor[FSCTF 2023]EZRC4[FSCTF 2023]ez_pycxor[FSCTF 2023]Tea_apk[FSCTF 2023]ezcode[FSCTF 2023]ezbroke[FSCTF 2023]rrrrust!!![FSCTF2023]ezrev&#xff08;未解决&#xff09; [FSCTF 2023]signin UPX壳&am…

redis-cluster集群模式

Redis-cluster集群 1 Redis3.0引入的分布式存储方案 2集群由多个node节点组成,redis数据分布在节点之中,在集群之中分为主节点和从节点3集群模式当中,主从一一对应,数据写入和读取与主从模式一样&#xff0c;主负责写&#xff0c;从只能读4集群模式自带哨兵模式&#xff0c;可…

自然资源土地管理法律法规知识竞赛这么办才高端

近些年&#xff0c;全国各地自然资源厅举办了土地管理法律法规知识竞赛&#xff0c;从我公司承办的这些赛事来看&#xff0c;传统的必答题、抢答题、风险题的方式已无法激起现场比赛气氛&#xff0c;需要更加复杂有趣的环节设置及高端竞赛软件及其配套设备加持才可以让知识竞赛…

什么是交易量价差分析法?anzo Capital一分钟讲明白

交易量价差分析法是一种深入的市场分析方法&#xff0c;它主要探讨了价格、价差和交易量之间的相互关系。在此过程中&#xff0c;交易量主要揭示了市场上的交易活动情况&#xff0c;而价差则反映了这些交易的价格变动。 为了更准确地理解这种关系&#xff0c;定义了交易量价差…

单元测试-java.lang.NullPointerException

报错信息 java.lang.NullPointerException 空指针异常 空对象引用 来源 对Controller层进行单元测试&#xff0c;解决完Spring上下文报错后继续报错。 解决 在测试方法执行前要为字段完成对象的注入&#xff0c;否则就报空指针异常。 测试例子 public class SysUserContr…

前端css粘性布局,顶部吸附效果(position: sticky)

sticky属性设置 /* 设置粘性布局 */ position: sticky; /* 拖动滚动条&#xff0c;当前元素超出文档0的位置时&#xff0c;触发定位效果&#xff08;同级元素位置不会受影响&#xff09; */ top: 0;页面初始效果 设置前&#xff08;滚动页面时&#xff0c;标签栏随页面滚动&a…

【深度学习】六大聚类算法快速了解

在机器学习中&#xff0c;无监督学习一直是我们追求的方向&#xff0c;而其中的聚类算法更是发现隐藏数据结构与知识的有效手段。目前如谷歌新闻等很多应用都将聚类算法作为主要的实现手段&#xff0c;它们能利用大量的未标注数据构建强大的主题聚类。本文从最基础的 K 均值聚类…

【二叉树进阶题目】236. 二叉树的最近公共祖先,JZ36 二叉搜索树与双向链表

二叉树进阶题目 236. 二叉树的最近公共祖先解题思路及实现思路一思路二 JZ36 二叉搜索树与双向链表描述解题思路及实现 236. 二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个…

Axios 拦截器 请求拦截器 响应拦截器

请求拦截器 相当于一个关卡&#xff0c;如果满足条件就放行请求&#xff0c;不满足就拦截 响应拦截器 在处理结果之前&#xff0c;先对结果进行预处理&#xff0c;比如&#xff1a;对数据进行一下格式化的处理 全局请求拦截器 axios.interceptors.request.use(config > { /…

SeaTunnel及SeaTunnel Web部署指南(小白版)

现在你能搜索到的SeaTunnel的安装。部署基本都有坑&#xff0c;官网的文档也是见到到相当于没有&#xff0c;基本很难找到一个适合新手小白第一次上手就能成功安装部署的版本&#xff0c;于是就有了这个部署指南的分享&#xff0c;小主已经把可能遇到的坑都填过了&#xff0c;希…

Web前端—移动Web第五天(媒体查询、Bootstrap、综合案例-alloyTeam)

版本说明 当前版本号[20231122]。 版本修改说明20231122初版 目录 文章目录 版本说明目录移动 Web 第五天01-媒体查询基本写法书写顺序案例-左侧隐藏媒体查询-完整写法关键词 / 逻辑操作符媒体类型媒体特性 媒体查询-外部CSS 02-Bootstrap简介使用步骤下载使用 栅格系统全局…

PTA 六度空间

“六度空间”理论又称作“六度分隔&#xff08;Six Degrees of Separation&#xff09;”理论。这个理论可以通俗地阐述为&#xff1a;“你和任何一个陌生人之间所间隔的人不会超过六个&#xff0c;也就是说&#xff0c;最多通过五个人你就能够认识任何一个陌生人。”如图1所示…