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

Linux进程间通信(上)

目录

一、无名管道PIPE

二、有名管道FIFO

三、内存映射mmap


进程间通信IPC(Inter Process Communicating)主要包括:

        无名管道pipe、有名管道fifo、内存映射mmap、共享内存shm,消息队列msg、信号signal、套接字socket(多机之间,多用于网络编程)

一、无名管道PIPE

        管道,单工通信,通常指无名管道(无名在于它是伪文件),存在(运行)内存,只能用于具有亲缘关系的父子进程或兄弟进程(管道可共享于2个进程以上),因为管道数据是通过队列来维护的,一端固定只能读或写,管道建立时会创建两个文件描述符分别用于读写管道,所以只能用文件IO来操作管道中的数据只能读一次,再读也没内容 ​​​​​​

int pipe(int fd[2]);

@param: 大小为2的int型数组,用来保存创建的两个文件描述符,fd[0]用来读、fd[1]用来写
    
@return:成功返回0,失败返回-1    

读写特性:

1.读管道:

(1)管道中有数据,read从头读数据,返回实际读到的字节数

(2)管道中无数据且写端没有关闭时,read阻塞等待数据写入;写端关闭时,read返回0

2.写管道:

(1)读端全部关闭,“管道会发生爆裂”,进程异常终止,可捕捉SIGPIPE来让进程不终止

(2)读端没有全部关且管道未满,正常追加写入,write返回实际写入字节数;管道满了(大小64K),write阻塞

二、有名管道FIFO

        一种文件类型,特殊文件有路径名与之关联,但数据存在运行内存中(ls -la命令查看文件大小始终为0),可在任意无关进程之间交换数据一端只读或只写半双工通信,不支持lseek操作,遵循先进先出,同样,FIFO中的数据读一次就清空了,读FIFO从头读,写FIFO追加写


功能:创建或打开fifo
int mkfifo(char *pathname, mode_t mode)

@param:	pathname 创建时给FIFO取个名 
    			 打开时指定FIFO
    
    	mode	 创建时,mode不用加O_CREAT,直接赋值权限即可
    			 打开时,mode设置O_WRONLY/O_RDONLY/O_RDWR 三选一
    
@return:成功返回0,失败返回-1(若存在同名fifo,创建失败,errno置EEXIST)

注意事项:

        open fifo时,某进程只读或只写打开(mode设置O_WRONLY/O_RDONLY),会默认阻塞。若mode中或上O_NONBLOCK,则为非阻塞状态。

        1)读写进程都默认阻塞时:先运行写或者读进程(被阻塞),再运行读或者写进程,不再阻塞,可以正常读写。

        2)读进程非阻塞时先运行写进程(被阻塞),再运行读进程,可以正常读写;先运行读进程,直接崩溃,因为没数据的情况下还不阻塞读!!!

        3)写进程非阻塞时:只能先运行读进程,再运行写进程

        关于数据完整性,多个进程写同一个管道时,如果写入数据长度<=4K,要么全部写入,要么一个字节都不写入(遵循先进先出);如果写入数据长度过长会导致数据交错

三、内存映射mmap

        内存映射可以通过mmap()映射普通文件将一个磁盘文件映射到进程自身的地址空间中,进程访问它通过返回的指针即可,不必调用read/write,全双工通信,因为访问内存的时间是纳秒级的,而访问磁盘是毫秒级的,大大提升了通信效率,适合于需要频繁读写大文件的场景

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
功能:申请创建 文件的内存映射区
    
@param:	
		addr 	映射区目的地址,一般设置为NULL,操作系统自动分配,可通过返回值获取
    	length 	必须>0 映射区的字节数,从文件开头offset个字节开始算起
        prot 	指定共享内存的访问权限 PROT_READ、PROT_WRITE、PROT_EXEC、PROT_NONE
        flags 	常用的有:MAP_SHARED共享的、MAP_PRIVATE私有的,频繁访问磁盘操作时、MAP_ANOYMOUS匿名映射(用于无fd文件,比如父子进程间通信)
        fd 		文件描述符,匿名映射时为-1
        offset 	偏移量,指从文件头偏移offset个字节开始映射,一般都给0表示完整映射到映射区
@return:    
		成功返回映射区的地址,后续的读写操作通过这个地址
        失败返回MAP_FAILED
int munmap(void *addr, size_t length)
功能:释放内存映射,即断开连接

@param: addr 映射区首地址  length 映射区大小    

注意事项:

        创建映射区出错概率很高,应养成返回值查错习惯!

        flags为MAP_SHARED时,要求指定的共享内存访问权限<=open的文件权限;为MAP_PRIVATE时,只需要文件有可读权限即可,操作仅对内存有效,不会写入到磁盘,且不能在进程间共享

        要映射的文件大小必须>0,否则会报错“总线错误”,系统所分配的映射区大小是以4K(一页内存大小)为单位的,文件大小<4K,系统仍分配4K,超过文件大小的范围可以访问,但仅仅是访问,无法真正写入文件

        共享内存映射成功后,可以立即关闭文件,对后续共享内存的操作无影响

        offset的偏移量必须为0/4K的整数倍


http://www.kler.cn/a/417559.html

相关文章:

  • 点(线)集最小包围外轮廓效果赏析
  • JavaScript前后端交互-AJAX/fetch
  • Linux 安装 RabbitMQ
  • Page Assist - 本地Deepseek模型 Web UI 的安装和使用
  • C#面试常考随笔13: 泛型的主要约束和次要约束是什么?
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.19 线性代数核武器:BLAS/LAPACK深度集成
  • android-studio 下载并安装
  • 如何正确书写sh文件/sh任务?bash任务
  • 数据结构-最小生成树
  • vue3+ant design vue实现日期选择器默认显示当前年,并限制用户只能选择当前年及之前~
  • Astra+ 深度相机系统架构解析:组件功能、数据流和应用领域
  • YOLO系列论文综述(从YOLOv1到YOLOv11)【第5篇:YOLOv3——多尺度预测】
  • JMeter中获取随机数、唯一ID、时间日期(包括当前日期增减)截取指定位数的字符等
  • 853 有边数限制的最短路(bellman-ford贝尔曼福特算法)
  • MySQL常见面试题(一)
  • A*(A-star)算法
  • qt QGraphicsEllipseItem详解
  • 电气火灾式故障电弧探测器在某医院照明回路中的应用
  • 第七课 Unity编辑器创建的资源优化_UI篇(UGUI)
  • Java中TimedCache缓存对象的详细使用
  • 力扣--LCR 149.彩灯装饰记录I
  • RAG数据拆分之PDF
  • Java Stream reduce 函数,聚合数据
  • html 中的 <code>标签
  • uniapp的video组件截图(抓拍)功能,解决截后为黑图bug
  • MySQL中的锁与MVCC