mmap()函数:

void *mmap(void* addr,size_t length,int port,int flags,int fd,off_t offset);

返回:成功:返回创建的映射区首地址;失败:MAP_FAILED 宏

参数:

addr:      建立映射区的首地址,由linux内核决定。使用时直接传递NULL;

length:   欲创建映射区的大小

port:    映射区权限PROT _READ、PROT_WRITE 、PROT _READ|PROTWRITE

flags:   标志位参数(常用于设定更新物理区域、设置共享、创建匿名映射区)

MAP_SHARED:     会将映射区所做的操作反射到物理设备上

MAP_PRIVATE:     映射区所作的修改不会反映到物理设备。

fd:       用来建立映射区的文件描述符

offset:  映射文件的偏移(4K的整数倍)

/***
mmap.c
***/
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/mman.h> int main()
{
int len,ret;
char *p = NULL;
int fd = open("mytest.txt",O_CREAT|O_RDWR,);
if(fd < )
{
perror("open error:");
exit();
}
len = ftruncate(fd,);
if(- == len)
{
perror("ftruncate error:");
exit();
}
p = mmap(NULL,,PROT_READ|PROT_WRITE,MAP_SHARED,fd,);
if(p == MAP_FAILED)
{
perror("mmap error:");
exit();
}
strcpy(p,"abc"); ret = munmap(p,);
if(- == ret)
{
perror("mmap error:");
exit();
}
close(fd);
return ;
}

运行结果:

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ gcc mmap.c -o mmap

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ ./mmap

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ cat mytest.txt

abc

mmap在使用过程中注意以下事项:

  1. 创建映射区的过程中,隐含着一次对映射文件的读操作。
  2. 当MAP_SHARED时,要求:映射区的权限  <= 文件打开的权限(出于对映射区的保护)。而MAP_PRIVATE则无所谓,因为mmap中的权限时对内存的限制。
  3. 映射区的释放和文件关闭无关。只要映射成功,文件可以立刻关闭。
  4. 特别注意:当映射文件大小为0时,不能创建映射区。所以:用于映射的文件必须有实际大小。mmap使用时常常会出现总线错误,通常是因为共享文件存储空间大小所引起的。
  5. munmap传入的地址一定是mmap的返回地址,坚决杜绝指针++操作
  6. 如果使用文件偏移,则值必须是4K的整数倍
  7. mmap创建映射区出错概率极高,一定要检查返回值,确保映射区建立成功再进行后续操作。

mmap父子进程间通信:

文件inode属性

struct stat

{

存储指针地址;

大小;

权限;

类型;

所以者;

}

/***
mmap_fork.c
***/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h> int var = ; int main()
{
int *p;
pid_t pid; int fd;
fd = open("temp",O_RDWR|O_CREAT|O_TRUNC,);
if(fd < )
{
perror("open error");
exit();
}
unlink("temp");
ftruncate(fd,); p = (int*)mmap(NULL,,PROT_READ|PROT_WRITE,MAP_SHARED,fd,);
if(p == MAP_FAILED)
{
perror("mmap error");
exit();
}
close(fd); pid = fork();
if( == pid)
{
*p = ;
var = ;
printf("child, *p = %d, var = %d\n",*p,var);
}
else
{
sleep();
printf("parent, *p = %d, var = %d\n",*p,var);
wait(NULL); int ret = munmap(p,);
if(- == ret)
{
perror("munmap error");
exit();
}
}
return ;
}

运行结果:

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ gcc mmap_fork.c -o mmap_fork

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ ./mmap_fork

child, *p = 2000, var = 1000

parent, *p = 2000, var = 100

mmap创建匿名映射区

/***
fork_mmap_linux.c
***/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h> int var = ; int main()
{
int *p;
pid_t pid; p = (int*)mmap(NULL,,PROT_READ|PROT_WRITE,MAP_SHARED | MAP_ANON,-,);
if(p == MAP_FAILED)
{
perror("mmap error");
exit();
} pid = fork();
if( == pid)
{
var = ;
*p = ;
printf("child, *p = %d,var = %d\n",*p,var);
}
else
{
sleep();
// printf("parent,*p = %d\n",*p);
printf("child, *p = %d,var = %d\n",*p,var);
wait(NULL);
int ret = munmap(p,);
if(- == ret)
{
perror("munmap error");
exit();
}
}
return ;
}

运行结果:

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ gcc fork_map_linux.c -o fork_map_linux

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ ./fork_map_linux

child, *p = 2000,var = 1000

child, *p = 2000,var = 100

注意:MAP_ANONYMOUS和MAP_ANON 这两个宏是linux操作系统特有的宏,再类Unix系统中如无该宏的定义,可以使用以下步骤来完成匿名映射区的建立。

  1. fd = open(“/dev/zero”,O_RDWR);
  2. p = mmap(NULL,size,PROT_READ|PROT_WRITE,MMAP_SHARED,fd,0);
/***
fork_map_anon.c
***/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h> int var = ; int main()
{
int *p;
pid_t pid;
int fd = open("/dev/zero",O_RDWR); p = (int*)mmap(NULL,,PROT_READ|PROT_WRITE,MAP_SHARED,fd,);
if(p == MAP_FAILED)
{
perror("mmap error");
exit();
} pid = fork();
if( == pid)
{
var = ;
*p = ;
printf("child, *p = %d,var = %d\n",*p,var);
}
else
{
sleep();
// printf("parent,*p = %d\n",*p);
printf("child, *p = %d,var = %d\n",*p,var);
wait(NULL);
int ret = munmap(p,);
if(- == ret)
{
perror("munmap error");
exit();
}
}
return ;
}

运行结果:

buntu1604@ubuntu:~/wangqinghe/linux/20190807$ gcc fork_map.c -o fork_map

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ ./fork_map

child, *p = 2000,var = 1000

child, *p = 2000,var = 100

mmap无血缘关系进程间通信:

/***
mmap_w.c
***/
#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/mman.h>
#include<string.h> struct STU
{
int id;
char name[];
char sex;
}; void sys_err(char *str)
{
perror(str);
exit();
} int main(int argc,char ** argv)
{
int fd;
struct STU student = {,"xiaoming",'m'};
char *mm; if(argc < )
{
printf("./a.out file_shared\n");
exit(-);
} fd = open(argv[],O_RDWR | O_CREAT,);
ftruncate(fd,sizeof(student)); mm = mmap(NULL,sizeof(student),PROT_READ|PROT_WRITE,MAP_SHARED,fd,);
if(mm == MAP_FAILED)
{
sys_err("mmap error");
} close(fd); while()
{
memcpy(mm,&student,sizeof(student));
student.id++;
sleep();
} munmap(mm,sizeof(student));
return ;
}
/***
mmap_r.c
***/
#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/mman.h>
#include<string.h> struct STU
{
int id;
char name[];
char sex;
}; void sys_err(char *str)
{
perror(str);
exit();
} int main(int argc,char ** argv)
{
int fd;
struct STU student;
struct STU *mm; if(argc < )
{
printf("./a.out file_shared\n");
exit(-);
} fd = open(argv[],O_RDONLY);
if(- == fd)
sys_err("open error"); mm = mmap(NULL,sizeof(student),PROT_READ,MAP_SHARED,fd,);
if(mm == MAP_FAILED)
{
sys_err("mmap error");
} close(fd); while()
{
printf("id=%d,name = %s,%c\n",mm->id,mm->name,mm->sex);
sleep();
} munmap(mm,sizeof(student));
return ;
}

Linux进程通信之mmap的更多相关文章

  1. linux 进程通信之 mmap

    一,管道PIPE 二,FIFO通信 三,mmap通信 创建内存映射区. #include <sys/mman.h> void *mmap(void *addr, size_t length ...

  2. Linux进程通信----匿名管道

    Linux进程通信中最为简单的方式是匿名管道 匿名管道的创建需要用到pipe函数,pipe函数参数为一个数组表示的文件描述字.这个数组有两个文件描 述字,第一个是用于读数据的文件描述符第二个是用于写数 ...

  3. Linux 进程通信之 ——信号和信号量总结

    如今最经常使用的进程间通信的方式有:信号,信号量,消息队列,共享内存.       所谓进程通信,就是不同进程之间进行一些"接触",这种接触有简单,也有复杂.机制不同,复杂度也不一 ...

  4. Linux进程通信学习总结

    http://blog.csdn.net/xiaoweibeibei/article/details/6552498 SYSV子系统的相关概念   引用标识符:引用标识符是一个整数,表示每一个SYSV ...

  5. Linux进程通信的几种方式总结

    进程通信的目的 数据传输 一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间 共享数据 多个进程想要操作共享数据,一个进程对共享数据 通知事 一个进程需要向另一个或一组进程发 ...

  6. linux进程通信之管道

    1.介绍: 1)同一主机: unix进程通信方式:无名管道,有名管道,信号 system v方式:信号量,消息队列,共享内存 2)网络通信:Socket,RPC 2.管道: 无名管道(PIPE):使用 ...

  7. linux 进程通信之 共享内存

    共享内存是被多个进程共享的一部分物理内存.共享内存是进程间共享数据的一种最快的方法.一个进程向共享内存区域写入了数据,共享这个内存区域的全部进程就能够立马看到当中的内容. 关于共享内存使用的API k ...

  8. linux 进程通信之 信号

    一,管道PIPE 二,FIFO通信 三,mmap通信 四,信号的概念 信号的特点:简单,但不能携带大量的信息,满足特定条件就会发生 信号的机制:进程B发送信号给进程A.信号是由内核来处理的. 信号的产 ...

  9. linux进程通信

    e14: 进程间通信(进程之间发送/接收字符串/结构体): 传统的通信方式: 管道(有名管道 fifo,无名管道 pipe) 信号 signal System V(基于IPC的对象):         ...

随机推荐

  1. java代码检出打包

    这里先提下前提,就是有个维护的(可能有二期的一个项目),后端是Java,由于很久都不做Java,剩下的只是不多了.之前做的Java容器要么是tomcat,要么接触过新的spring cloud.从来没 ...

  2. (七)Action之ActionContext(OGNL表达式的使用)

    一.ActionContext的重要性 struts中的数据都存放在ActionContext里,所以这部分是Action中的核心. ActionContext又称广义值栈,既然有广义值栈就有侠义值栈 ...

  3. javadoc 自动生成java帮助文档

    用法: javadoc [options] [packagenames] [sourcefiles] 选项: -public 仅显示 public 类和成员 -protected 显示 protect ...

  4. taglist and nerdtree

    函数:function! s:Tlist_Window_Exit_Only_Window()中的winbunr(2)改为winbunr(3),即只剩2个窗口时关闭,考虑到2个窗口肯定是同时存在,所以这 ...

  5. Nginx与负载均衡

    Nginx,首先是一款轻量级的Web服务器,其特点是占有内存少,并发能力强,大厂用户有:百度.新浪.网易.腾讯等.其次,它是一款反向代理服务器:第三,它还是一款电子邮件(IMAP/POP3)代理服务器 ...

  6. kong网关: service+route+upstream

    对于刚开始学习kong网关,总是一脑子浆糊迷迷糊糊.虽然已经安装好,但却不知道接下来如何下手, 因为包含项太多:service.routes.upstream.consumer.plugins等等.一 ...

  7. laravel中引入composer安装在vendor中的第三方组件

    一.安装第三方组件 方法一:使用命令行安装第三方(已phpword为例): composer require phpoffce/phpword ^v0..* 方法二: 修改主项目composer.js ...

  8. LINUX档案权限

    一.ls命令显示目录详细信息 列表显示目录内容 : ls drwxr-xr-x.  4 root   root       4096 Jun 26 02:07 acpi -rw-r--r--.  1 ...

  9. Computer Vision_33_SIFT:SIFTflow Dense Correspondence across Scenes and its Applications——2011

    此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...

  10. http服务详解(2)——httpd的配置文件常见设置

    HTTP服务器应用 http服务器程序 httpd apache nginx lighttpd 应用程序服务器 IIS .asp tomcat .jsp jetty 开源的servlet容器,基于Ja ...