- 浏览: 19810 次
最新评论
Linux进程间通信源码剖析,共享内存
2010年12月21日
来自:http://blog.csdn.net/dancing999/archive/2008/01/13 /2042473.aspx
范例1:两个进程通过映射普通文件实现共享内存通信
范例1包含两个子程序:map_normalfile1.c及map_normalfile2.c。编译两个程序,可执行文件分别为map_normalfile1及map_normalfile2。两个程序通过命令行参数指定同一个文件来实现共享内存方式的进程间通信。map_normalfile2试图打开命令行参数指定的一个普通文件,把该文件映射到进程的地址空间,并对映射后的地址空间进行写操作。map_normalfile1把命令行参数指定的文件映射到进程地址空间,然后对映射后的地址空间执行读操作。这样,两个进程通过命令行参数指定同一个文件来实现共享内存方式的进程间通信。
下面是两个程序代码: /*-------------map_normalfile2.c写文件-----------*/ #include #include #include #include typedef struct{ char name[4]; int age; }people; main(int argc, char** argv) // map a normal file as shared mem: { int fd,i; people *p_map; char temp; fd=open(argv[1],O_CREAT|O_RDWR|O_TRUNC,00777); lseek(fd,sizeof(people)*5-1,SEEK_SET); write(fd,"",1); p_map = (people*) mmap( NULL,sizeof(people)*10,PROT_READ|PROT_WRITE,MAP_SH ARED,fd,0 ); close( fd ); temp = 'a'; for(i=0; i #include #include #include typedef struct{ char name[4]; int age; }people; main(int argc, char** argv) // map a normal file as shared mem: { int fd,i; people *p_map; fd=open( argv[1],O_CREAT|O_RDWR,00777 ); p_map = (people*)mmap(NULL,sizeof(people)*10,PROT_READ|PRO T_WRITE,MAP_SHARED,fd,0); for(i = 0;i内存区的数据往往是有固定格式的,这由通信的各个进程决定,采用结构的方式有普遍代表性)。map_normfile1首先打开或创建一个文件,并把文件的长度设置为5个people结构大小。然后从mmap()的返回地址开始,设置了10个people结构。然后,进程睡眠10秒钟,等待其他进程映射同一个文件,最后解除映射。
map_normfile2.c只是简单的映射一个文件,并以people数据结构的格式从mmap()返回的地址处读取10个people结构,并输出读取的值,然后解除映射。
分别把两个程序编译成可执行文件map_normalfile1和map_normalfile2后,在一个终端上先运行./map_normalfile2 /tmp/test_shm,程序输出结果如下:
initialize over
umap ok
在map_normalfile1输出initialize over 之后,输出umap ok之前,在另一个终端上运行map_normalfile2 /tmp/test_shm,将会产生如下输出(为了节省空间,输出结果为稍作整理后的结果):
name: b age 20; name: c age 21; name: d age 22; name: e age 23; name: f age 24;
name: g age 25; name: h age 26; name: I age 27; name: j age 28; name: k age 29;
在map_normalfile1 输出umap ok后,运行map_normalfile2则输出如下结果:
name: b age 20; name: c age 21; name: d age 22; name: e age 23; name: f age 24;
name: age 0; name: age 0; name: age 0; name: age 0; name: age 0;
从程序的运行结果中可以得出的结论
1、 最终被映射文件的内容的长度不会超过文件本身的初始大小,即映射不能改变文件的大小;
2、 可以用于进程通信的有效地址空间大小大体上受限于被映射文件的大小,但不完全受限于文件大小。打开文件被截短为5个people结构大小,而在map_normalfile1中初始化了10个people数据结构,在恰当时候(map_normalfile1输出initialize over 之后,输出umap ok之前)调用map_normalfile2会发现map_normalfile2将输出全部10个people结构的值,后面将给出详细讨论。 注:在linux中,内存的保护是以页为基本单位的,即使被映射文件只有一个字节大小,内核也会为映射分配一个页面大小的内存。当被映射文件小于一个页面大小时,进程可以对从mmap()返回地址开始的一个页面大小进行访问,而不会出错;但是,如果对一个页面以外的地址空间进行访问,则导致错误发生,后面将进一步描述。因此,可用于进程间通信的有效地址空间大小不会超过文件大小及一个页面大小的和。
3、 文件一旦被映射后,调用mmap()的进程对返回地址的访问是对某一内存区域的访问,暂时脱离了磁盘上文件的影响。所有对mmap()返回地址空间的操作只在内存中有意义,只有在调用了munmap()后或者msync()时,才把内存中的相应内容写回磁盘文件,所写内容仍然不能超过文件的大小。
范例2:父子进程通过匿名映射实现共享内存 #include #include #include #include typedef struct{ char name[4]; int age; }people; main(int argc, char** argv) { int i; people *p_map; char temp; p_map=(people*)mmap(NULL,sizeof(people)*10,PROT_RE AD|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0); if(fork() == 0) { sleep(2); for(i = 0;iread: the %d people's age is %d\n",i+1,(*(p_map+i)).age); (*p_map).age = 100; munmap(p_map,sizeof(people)*10); //实际上,进程终止时,会自动解除映射。 exit(); } temp = 'a'; for(i = 0;iread: the first people,s age is %d\n",(*p_map).age ); printf("umap\n"); munmap( p_map,sizeof(people)*10 ); printf( "umap ok\n" ); } 考察程序的输出结果,体会父子进程匿名共享内存:
child read: the 1 people's age is 20
child read: the 2 people's age is 21
child read: the 3 people's age is 22
child read: the 4 people's age is 23
child read: the 5 people's age is 24
parent read: the first people,s age is 100
umap
umap ok
发表评论
-
S3C2410内存管理单元MMU基础实验
2012-01-20 08:14 1074S3C2410内存管理单元MMU基 ... -
转:linux设备模型之pci设备的I/O和内存
2012-01-20 08:14 849转:linux设备模型之pci设备的I/O和内存 2011年 ... -
嵌入式Linux内核移植相关代码分析
2012-01-20 08:14 678嵌入式Linux内核移植相 ... -
linux NAND驱动之一:内核中的NAND代码布局
2012-01-20 08:14 1435linux NAND驱动之一:内核 ... -
妙用script自动清除ie地址栏记录
2012-01-19 13:30 690妙用script自动清除ie地址栏记录 2012年01月13 ... -
bat在win7中获取当前路径
2012-01-19 13:30 1191bat在win7中获取当前路径 ... -
系统文件递归查询
2012-01-19 13:30 691系统文件递归查询 2012年01月11日 文件系统对象也 ... -
深入浅出Win2000 (xp)计算机启动/关机脚本
2012-01-19 13:30 959深入浅出Win2000 (xp)计算 ... -
脚本病毒
2012-01-19 13:30 780脚本病毒 2011年04月30日 脚本病毒通常是Java ... -
WinCE驱动开发问题精华集锦(一)
2012-01-17 03:20 496WinCE驱动开发问题精华 ... -
速度-电脑运行速度慢的各种原因及解决方法zz
2012-01-17 03:20 531速度-电脑运行速度慢的 ... -
系统常见死机原因解析及解决方法
2012-01-17 03:20 543系统常见死机原因解析 ... -
针对WM6.5系统和软件的注册表修改以及优化
2012-01-17 03:19 1173针对WM6.5系统和软件的注册表修改以及优化 2011年04 ... -
深入Java核心Java内存分配原理精讲
2012-01-17 03:19 776深入Java核心Java内存分配原理精讲 2011年03月0 ... -
古代的吴越男人是找不到汉人老婆,甚至很难找到吴越老婆的
2012-01-16 01:53 1570古代的吴越男人是找不 ... -
我的贵州 (一)
2012-01-16 01:53 617我的贵州 (一) 2011年06月08日 贵州不 ... -
我非英雄,广目无双,我本坏蛋,无限嚣张
2012-01-16 01:53 1098我非英雄,广目无双,我 ... -
宋小鱼孙二狗之“长相”
2012-01-16 01:53 533宋小鱼孙二狗之“长相 ... -
东北民众的地方语言
2012-01-16 01:53 513东北民众的地方语言 20 ... -
json访问
2012-01-11 01:52 474json访问 2011年08月01日 [{" ...
相关推荐
linux进程间通信编程之共享内存实例程序。
Linux环境进程间通信(五) 共享内存(上)
本文主要介绍Linux进程间通信中共享内存的知识,感兴趣的朋友可以看看。
Linux系统中的进程间通信是典型的虚拟内存系统中的进程间通信:Linux 的进程间通信是不同进程间交换数据的机制。由于Linux系统支持虚拟内 存, 对于每一个进程,系统会为它分配一个单独的进程空间,不同的进程有不同...
目录 深刻理解Linux进程间通信(IPC) 1 Linux环境进程间通信(一) 3 ...Linux环境进程间通信(五): 共享内存(上) 63 Linux环境进程间通信(五): 共享内存(下) 73 Linux 环境进程间通信(六) 79
linux下C语言编程4-使用共享内存实现进程间通信
Linux进程间通信.pdf Linux进程间通信.pdf
自己做的一个ppt通过共享内存的方式实现进程间的通信
操作系统实验报告(LINUX进程间通信)
里面是两个实验,一个共享内存方式的进程间通信,另一个是shell命令解释器。两个都是linux版本的。
之前用过Prosix版本的共享内存和信号量,一直没有实践System V版本的,主要是因为其信号量集的概念操作有些复杂,今天试着写一个SV版本的共享内存进程间通信,使用信号量同步。程序提供了几个简单的用于操作SV版本...
Linux进程间通信--Linux进程间通信--Linux进程间通信--Linux进程间通信
讲解了下linux共享内存函数
管道 信号 共享内存
linux进程间通信ppt,华清远见出品,还是很不错的
linux c 进程间通信 共享内存的操作 源代码
linux c 进程间通信(共享内存+消息队列)
Linux_进程间通信_-_共享内存shmget方式