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。