Linux系统【五】进程间通信-共享内存mmap

mmap函数

#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);

参数:

  • void *addr建立映射区的首地址,由Linux内核指定,所以我们直接传递NULL。也就是说虽然这是一个参宿但是并不需要我们传递,当建立好映射区以后映射区的首地址将以返回值返回。
  • size_t length建立映射区的大小,一般由创建映射区的文件的大小
  • int prot用来表示映射区的权限(读,写,读写,执行,对于执行一般是操作系统调用)。PROT_READ PORT_WRITE PROT_READ | PROT_WRITE
  • int flags标志位参数,可以通过设置标志位来决定对映射区的修改是否反应到磁盘上。
    • MAP_SHEARD会将映射区所做的修改反映到物理设备上
    • MAP_PRIVATE映射区所做的修改不会反映到物理设备
  • int fd用来建立映射区的文件描述符
  • off_t offset映射文件的偏移,用于截取文件的一部分建立映射区(4K的整数倍)
    返回值:
    成功返回创建映射区的首地址。失败返回MAP_FAILED

ftruncate用来扩展文件大小
关闭映射区:

int munmap(void *addr, size_t length);

第一个参数必须是映射区的首地址,长度可以变化
成功返回0,失败返回-1

例如:

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<string.h>int main()
{int fd = open("mmap1file",O_CREAT | O_RDWR | O_TRUNC ,0644);if(-1 == fd){perror("open error");exit(1);}if(-1 == ftruncate(fd, 128)) 	{perror("ftruncate error:");exit(1);}char *p = mmap(NULL, lseek(fd,0,SEEK_END), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if(MAP_FAILED == p){perror("mmap error:");exit(1);}strcpy(p,"Hello mmap!");close(fd);	//关闭文件if(-1 == munmap(p,128)){perror("munmap error:");exit(1);}return 0;
}

注意事项

  • 可以用malloc创建大小为0 的堆空间,并且可以free, 不可以创建大小为0 的映射区
  • 如果文件是以只读方式打开的就不能改变文件大小
  • 如果文件是以只读方式打开,那么不能将映射区设置为MAP_SHARED,但是可以将映射区设置为MAP_PRIVATE
  • 如果文件以只写方式打开,将无法建立映射区,错误信息为Permission denied,因为创建映射区的过程中其实有一次隐含的读操作
  • 创建映射区的权限要小于等与文件的权限
  • 偏移量必须是页(4K)的整数倍
  • 因为mmap容易出错,所以一定要保留mmap的返回值,并通过perror输出错误信息
  • 关闭映射区的时候munmap的第一个参数必须是映射区的首地址
  • 建立映射区以后文件即使关闭也不影响,如果是MAP_SHARED的话仍旧会修改磁盘文件

利用共享内存在父子进程之间通信

用于通信的时候我们创建一个临时文件,成功创建映射区以后将文件关闭不再使用。

具体的方法是:

  1. 创建一个文件
  2. 使用ftruncate函数改变文件大小
  3. 使用unlink函数删除目录项(创建临时文件)
  4. 建立映射区
  5. 关闭文件

在父子进程间通信时MAP_SHARED指的是共享同一个映射区,MAP_PRIVATE指的是不共享映射区,父子进程分别占用

匿名映射

因为正常mmap函数必须依赖一个文件,虽然这个文件没有存在的必要,因此我们需要openftruncateunlinkclose比较麻烦。因此我们可以使用匿名映射较为方便地创建映射区。

int *p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

len可以根据我们的需要修改大小。
MAP_ANONYMOUS表示匿名通信,可以简写为MAP_ANON

需要注意的是MAP_ANONYMOUS只能够在Linux系统中使用,在其他类Unix系统中不可以使用,在其他系统中使用字符设备文件/dev/zero

int fd = open("/dev/zero", O_RDWR);
p = (int*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

mmap无血缘关系进程通信

同一个文件创建的是一个映射区,因此如果我们想要在没有血缘关系,就需要通过同一个文件来建立映射区

strace 可执行文件追踪程序里面所使用的系统调用有哪些

其实Linux系统对文件的操作是通过mmap进行的

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

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

相关文章

socket编程 -- epoll模型服务端/客户端通信的实现

https://blog.csdn.net/y396397735/article/details/50680359 本例实现如下功能&#xff1a; 支持多客户端与一个服务端进行通信&#xff0c;客户端给服务端发送字符串数据&#xff0c;服务端将字符串中小写转为大写后发送回客户端&#xff0c;客户端打印输出经转换后的字符串。…

Python3 面向对象程序设计

类的定义 Python使用class关键字来定义类 class Car:def infor(self):print("This is a car") car Car() car.infor()内置方法isinstance()来测试一个对象是否为某个类的实例 self参数 类的 所有实例方法都有一个默认的self参数&#xff0c;并且必须是方法的第一…

计算机网络【二】物理层基础知识

计算机网络的性能 速率&#xff1a;连接在计算机网络上的主机在数字信道上传送数据位数的速率&#xff0c;也成为data rate 或bit rate&#xff0c;单位是b/s,kb/s,Mb/s,Gb/s。 我们平时所讲的宽带的速度是以字为单位的&#xff0c;但是实际中应用一般显示的是字节 &#xff0…

Linux网络编程——tcp并发服务器(多进程)

https://blog.csdn.net/lianghe_work/article/details/46503895一、tcp并发服务器概述一个好的服务器,一般都是并发服务器&#xff08;同一时刻可以响应多个客户端的请求&#xff09;。并发服务器设计技术一般有&#xff1a;多进程服务器、多线程服务器、I/O复用服务器等。二、…

求序列第K大算法总结

参考博客&#xff1a;传送门 在上面的博客中介绍了求序列第K大的几种算法&#xff0c;感觉收益良多&#xff0c;其中最精巧的还是利用快速排序的思想O(n)查询的算法。仔细学习以后我将其中的几个实现了一下。 解法 1&#xff1a; 将乱序数组从大到小进行排序然后取出前K大&a…

Linux网络编程——tcp并发服务器(多线程)

https://blog.csdn.net/lianghe_work/article/details/46504243tcp多线程并发服务器多线程服务器是对多进程服务器的改进&#xff0c;由于多进程服务器在创建进程时要消耗较大的系统资源&#xff0c;所以用线程来取代进程&#xff0c;这样服务处理程序可以较快的创建。据统计&a…

计算机网络【三】物理层数据通信

物理层传输媒介 导向传输媒体&#xff0c;比如光纤和铜线 双绞线&#xff08;屏蔽双绞线STP 五屏蔽双绞线UTP&#xff09;电线扭曲在一起可以降低互相之间的电磁干扰 同轴电缆 (50欧姆的基带同轴电缆&#xff0c;75欧姆的宽带同轴电缆) 10M和100M网络只使用了四根线&#xf…

02_算法分析

02_算法分析 0.1 算法的时间复杂度分析0.1.1 函数渐近增长概念&#xff1a;输入规模n>2时&#xff0c;算法A1的渐近增长小于算法B1 的渐近增长随着输入规模的增大&#xff0c;算法的常数操作可以忽略不计测试二&#xff1a;随着输入规模的增大&#xff0c;与最高次项相乘的常…

Linux网络编程——I/O复用之select详解

https://blog.csdn.net/lianghe_work/article/details/46506143一、I/O复用概述I/O复用概念&#xff1a;解决进程或线程阻塞到某个 I/O 系统调用而出现的技术&#xff0c;使进程不阻塞于某个特定的 I/O 系统调I/O复用使用的场合&#xff1a;1.当客户处理多个描述符&#xff08;…

Linux多进程拷贝文件

学习了mmap以后&#xff0c;实现一个简单的小程序&#xff0c;进行多个进程对一个文件进行拷贝。 Linux mmap共享内存学习可以参考我的另一篇博客&#xff1a;传送门 实现思想 我们可以将原来的文件利用mmap分成多个段分别进行传输。 实现代码 #include<stdio.h> #…

斐波那契查找(Fibonacci Search)和折半查找

两个查找算法都是针对有序数组进行查找&#xff0c;不同点在于分界点的取值不同。 算法介绍 折半查找很简单&#xff0c;每次与当前区间的中点进行比较&#xff0c;然后决定查找前一部分还是后一部分。 Fibonacci查找利用了Fibonacci序列每一项等于前两项和的特点进行划分&a…

Linux网络编程——tcp并发服务器(I/O复用之select)

https://blog.csdn.net/lianghe_work/article/details/46519633与多线程、多进程相比&#xff0c;I/O复用最大的优势是系统开销小&#xff0c;系统不需要建立新的进程或者线程&#xff0c;也不必维护这些线程和进程。代码示例&#xff1a;#include <stdio.h> #include &l…

操作系统【二】死锁问题以及处理方法

死锁的概念 死锁&#xff1a;在并发环境下&#xff0c;个进程因为竞争资源而造成的一种互相等待对方手里的资源&#xff0c;导致各进程都阻塞&#xff0c;无法向前推进的现象。 区别&#xff1a; 饥饿&#xff1a;由于长期得不到想要的资源进程无法向前推进的现象。死循环&a…

Linux网络编程——I/O复用之poll函数

https://blog.csdn.net/lianghe_work/article/details/46534029一、回顾前面的selectselect优点&#xff1a;目前几乎在所有的平台上支持&#xff0c;其良好跨平台支持也是它的一个优点select缺点&#xff1a;1.每次调用 select()&#xff0c;都需要把 fd 集合从用户态拷贝到内…

操作系统【一】进程同步和信号量

基本概念 进程异步性特征&#xff1a;各并发执行的进程以各自独立的&#xff0c;不可预知的速度向前推进。 进程同步又称作直接制约关系&#xff0c;他是指为完成某种任务而建立的两个或者多个进程&#xff0c;这些进程因为需要在某些位置上协调他们的工作顺序而产生的制约关…

计算机网络【四】数据链路层基本概念+点到点通信(PPP协议)

数据链路层基本概念 路由器是网络层设备 数据链路层&#xff1a;数据管道&#xff0c;传输的是数据包加上发送地址&#xff0c;接收地址&#xff0c;校验的数据帧 数据链路层的信道类型&#xff1a; 点到点信道&#xff1a;使用一对一的点到点通信方式&#xff08;两个设备…

Linux网络编程——tcp并发服务器(poll实现)

https://blog.csdn.net/lianghe_work/article/details/46535859想详细彻底地了解poll或看懂下面的代码请参考《Linux网络编程——I/O复用之poll函数》 代码&#xff1a;#include <string.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#…

二分查找的最大比较次数

二分查找很简单&#xff0c;可是对于一个区间长度为n的数组&#xff0c;最大的比较次数为多少呢&#xff1f; 对于标准的二分查找&#xff0c;我们每次从区间[l,r)中取一个值&#xff0c;和中间值mid(lr)>>1进行比较&#xff0c;然后将数组分为[l,mid) [mid1,r)&#xf…

Linux网络编程——I/O复用函数之epoll

https://blog.csdn.net/lianghe_work/article/details/46544567一、epoll概述epoll 是在 2.6 内核中提出的&#xff0c;是之前的 select() 和 poll() 的增强版本。相对于 select() 和 poll() 来说&#xff0c;epoll 更加灵活&#xff0c;没有描述符限制。epoll 使用一个文件描述…