linux进程通信共享内存机制

1)概念:



1)Linux和所有UNIX操作系统允许共享内存通过共享内存在应用程序之间共享。



2)有API用于共享内存的进程之间功能的两种基本类型:系统V和POSIX。



3)在这两类函数上使用相同的原则,其核心思想是必须将任何要共享的内存分配给显示。



4)由于所有进程共享相同的内存,共享内存在各种进程间通信中效率最高。



5)内核不同步对共享内存的访问,因此我们必须提供我们自己的同步措施,例如,在写入数据之前,不允许其他进程读写。这里我们用等待来解决这个问题。



二)POSIX共享内存API



1)功能shm_open和shm_unlink是开放和unlink系统非常类似的呼吁为普通文件。



2)如果你想写一个便携式程序,然后shm_open和shm_unlink是最好的选择。



3)shm_open:创建一个新的共享区或连接到一个现有的共享区。该区域由其名称标识,函数返回每个文件的描述符。



4)shm_unlink:类似于unlink系统调用操作文件,直到所有的过程不再是指内存区域释放之前。



5):使用mmap映射一个文件到一个内存区域,在返回的文件描述符shm_open函数也使用。



6):用munmap释放内存映射通过mmap区域。



7)msync:同步访问映射区和写缓存的数据到物理内存,其他进程可以监控这些变化。



源程序1



#包括



#包括



#包括



#包括



#包括



#包括



#包括



无效error_out(const char*味精)



{



perror(MSG);



退出(exit_failure);



}



int main(int argc、argv char * { })



{



int r;



Const char *memname = /mymem;



const size_t region_size = sysconf(_sc_page_size);



int fd = shm_open(MEMNAME,o_creat | o_trunc | o_rdwr,0666);



如果(FD = 1)



error_out(shm_open );



R =函数(FD,region_size);



如果(r)!= 0)



error_out(函数);



void *ptr = mmap(0,region_size,prot_read | prot_write,map_shared,FD,0);



如果(ptr = map_failed)



error_out(mmap );



近距离(FD);



pid_t PID = fork();



如果(PID = 0){



u_long * a(PTR u_long *);



* a 0xdeadbeef;



出口(0);



}



别的{



国际地位;



Waitpid(PID,地位,0);



printf(孩子写% #基因



}



睡眠(50);



R = munmap(PTR,region_size);



如果(r)!= 0)



error_out(munmap );



R = shm_unlink(MEMNAME);



如果(r)!= 0)



error_out(shm_unlink );



返回0;



}



编译:



GCC啊postix SHM postix SHM。C LRT



/ postix SHM。



孩子写的0xdeadbeef



50秒后,程序退出。



程序分析:



1)程序执行的shm_open函数来创建一个共享内存区,当mymem文件创建在/ dev / SHM /。



2)变化的函数的大小的页面大小创建共享内存(sysconf(_sc_page_size))通过shm_open功能。如果你不执行函数功能,你将报告总线错误。



3)映射创建的mymem文件存储器通过mmap函数。



4)子进程是通过叉和共享区域映射是通过继承调用fork。



5)程序通过等待系统传输,以保持父进程和子进程之间的同步。



6)非父子进程也可以以共享内存区域的方式进行通信。



Linux共享内存的实现依赖于共享内存文件系统。文件系统通常是加载在。shm_open系统调用函数时,它将产生mymem文件 / / /目录结构健康监测系统的开发。



然后程序调用shm_unlink删除mymem,如果你卸载/ dev / SHM挂载点这里



查看分区信息



DF—H



文件系统大小使用%挂载



/ dev / sda1 19g 973m 17g 6% /



tmpfs 253m 0 253m 0% / / / RW lib init



udev 10m 88k 10M 1% / dev



tmpfs 253m 0 253m 0% / dev / SHM



卸载



umount / dev / SHM /



/ POSIX SHM。



孩子写的0xdeadbeef



{ 1 } 15476



LS—L / dev / SHM / mymem



- rw-R -R - 1根4096 2010-10-26 14:25 / / / mymem结构健康监测系统的开发



我们看到,shm_open只是创建一个文件 / dev / SHM,无论 / dev / SHM是一个分区,安装tmpfs类型。



如果你删除了



删除/ dev / SHM



再次执行POSIX SHM



/ POSIX SHM。



孩子写的0xdeadbeef



此时程序无法找到,并将共享内存文件设置在目录中。



LS—L / dev / mymem



- rw-R -R - 1根4096 2010-10-26 14:29 / dev / mymem



三)系统v共享内存API



1)系统api在X视窗系统及其扩展版本中得到了广泛的应用,也被许多X应用程序所使用。



2):创建一个新的shmget共享区或连接到一个现有的共享区域(与shm_open)。



3)调用shmat:用于映射文件到内存区(用mmap)。



4)shmdt:是用来释放内存映射区(与munmap)



5)shmctl:断开共享区域(与shm_unlink)多用户。



源程序2:



#包括



#包括



#包括



#包括



#包括



#包括



#包括



无效error_out(const char*味精)



{



perror(MSG);



退出(exit_failure);



}



int main(int argc、argv char * { })



{



key_t MyKey = 12345678;



const size_t region_size = sysconf(_sc_page_size);



Int SMID = shmget(MyKey,region_size,ipc_creat | 0666);



如果(SMID = 1)



error_out(shmget );



void*指针;



ptr = shmat(SMID,null,0);



如果(ptr = =(void * 1))



error_out(shmat );



pid_t PID = fork();



如果(PID = 0){



u_long * a(PTR u_long *);



* a 0xdeadbeef;



出口(0);



}



别的{



国际地位;



Waitpid(PID,地位,0);



printf(孩子写% #基因



}



睡眠(30);



int r = shmdt(PTR);



如果(r = - 1)



error_out(shmdt );



R = shmctl(SMID,ipc_rmid,null);



如果(r = - 1)



error_out(shmdt );



返回0;



}



GCC SysV SHM。C O SysV SHM -轻轨



/ SysV SHM。



孩子写的0xdeadbeef



程序分析:



1)通过使用shmget函数的key_t可变的功能相当于用shm_open文件名,和SMID shmget返回的功能相当于shm_open返回的文件描述符。



2)与POSIX的API创建的内存区域,通过系统V创建存储区API是不可见的任何文件系统。



3)你可以使用IPC系统V共享内存管理API。