linux mmap多进程通信,Linux 进程间通信(3) -- mmap共享映射区

进程间通信(IPC - InterProcess Communication)

通信的方式有很多: 文件, 管道, 信号, 共享内存, 消息队列, 套接字, 命名管道等等;

但是由于设计缺陷现在常用的有:

1.管道(简单, 默认匿名管道, 还有有名管道)

2.信号(开销小, 但是如果不是做系统编程一般不用, 因为缺点大于有点, 比如有没有收到无法确认)

3.共享映射区(无血缘关系之间)

4.本地套接字(最稳定)

三、 共享映射区

简述: 将本地磁盘上的文件映射(使用函数: void **mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);)到虚拟内存的加载动态库的区域, 这样便不用再去对文件进行操作, 直接对其内存上的地址进行操作就行了.

通信: 父子进程共享内存映射区, 那么创建内存映射区之后再fork子进程即可直接进行操作; 无血缘关系的, 他们可以同时映射同一个本地文件, 在对其进行读写操作, 但是该文件里的数据是不需要的.(重点)

API:

# include

void * mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);

参数:

void *addr: 内存中空间的地址, 以便映射, 但是我们是不知道的, 内核会处理, 一般传null

size_t len: 映射的长度, 一般是和文件的大小对应, 但是你需要映射多大就写多少

int prot: 映射区权限, 对应的是一些宏, 在man文档中查看, 我们一般都要用到读写权限: PORT_READ PORT_WRITE, 设置时必须有读权限

int flags: 对应的宏, 一般如果通信使用一般设置成MAP_SHARED

int fd: 映射的文件描述符

off_t offset: 映射文件的偏移量, 对应磁盘文件的偏移量, 设置时必须是4K的整数倍, 不需要指定时传0即可

返回值:

调用成功返回映射区的首地址, 失败返回MAP_FAILED即(void *)(-1)

映射区映射本地文件代码:

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc, const char* argv[])

{

int fd = open("test.txt", O_RDWR); //打开本地磁盘中的文件, 获取fd

if(fd == -1) {

perror("open error");

exit(1);

}

void* ptr = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

if(ptr == MAP_FAILED) {

perror("mmap error");

exit(1);

}

close(fd);

printf("buf = %s\n", (char*)ptr);//读取数据

// 修改映射区数据

strcpy(ptr, "99999999999999");

// 释放内存映射区

int ret = munmap(ptr, 1024);

if(ret == -1) {

perror("munmap error");

exit(1);

}

return 0;

}

注意:

1 如果对mmap的返回值(ptr)做++操作(ptr++), 那么释放时调用munmap会失败

2 如果open时O_RDONLY, mmap时prot参数指定

PROT_READ | PROT_WRITE会怎样?--会提示权限不够, 因为文件打开的时候是reonly, 但是映射区对应的待会还要写操作, 但是文件没有该权限

3 文件偏移量必须是4k的整数倍, 不然mmap出错

4 调用mmap时要注意权限问题, 偏移量问题, 长度问题(长度必须大于0, 不然没意义, 并且要求本地文件大小也是大于0的, 文件长度>=映射区长度)

5 open的时候O_CREAT一个新文件也可以来创建映射区但是前提是创建成功之后使用truncate(truncate)做文件拓展, fseek也可以拓展, 但是需要进行一次写操作

6 映射区创建成功之后, 文件就可以关闭了

7 对ptr越界操作会出现无效操作或段错误, 但是越界之后不会对文件有影响的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux中,mmap可以用于进程间通信。具体来说,通过使用mmap函数,内核可以帮助我们创建一个映射,多个进程可以利用这个映射来进行数据传递。即使进程之间没有血缘关系,也可以使用mmap来完成通信。为了实现共享,可以使用MAP_SHARED标志位参数。 在使用mmap进行进程通信时,需要注意以下几点: 1. 首先,要设置适当的标志位参数flags,如果想要实现共享,应该使用MAP_SHARED。 2. 第二个参数代表映射的大小,可以根据实际需要进行设置。 3. 特别需要注意的是,MAP_ANONYMOUS和MAP_ANON这两个宏是Linux操作系统特有的宏。如果在类Unix系统中没有定义这些宏,可以通过以下两个步骤来建立匿名映射: - 使用open函数打开/dev/zero文件,获取文件描述符fd。 - 使用mmap函数创建映射,其中fd参数为上一步中获取的文件描述符。 可以参考示例代码来更加清楚地理解这些步骤。 需要注意的是,mmap的本质就是利用文件进行进程间通信。它的优点在于不需要使用write/read函数,而是可以直接通过指针完成读写操作。因此,即使有许多其他的进程间通信方法,使用mmap直接通过文件完成进程间通信也是可行的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [linux 进程间通信-mmap](https://blog.csdn.net/ShenHang_/article/details/106689488)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值