Linux共享内存实现机制的详解
Linux共享内存实现机制的详解
内存共享:两个不同进程A、B共享内存的意思是,同⼀块物理内存被映射到进程A、B各⾃的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同⼀块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。
效率:采⽤共享内存通信的⼀个显⽽易见的好处是效率⾼,因为进程可以直接读写内存,⽽不需要任何数据的拷贝。对于像管道和消息队列等通信⽅式,则需要在内核和⽤户空间进⾏四次的数据拷贝,⽽共享内存则只拷贝两次数据[1]:⼀次从输⼊⽂件到共享内存区,另⼀次从共享内存区到输出⽂件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建⽴共享内存区域。⽽是保持共享区域,直到通信完毕为⽌,这样,数据内容⼀直保存在共享内存中,并没有写回⽂件。共享内存中的内容往往是在解除映射时才写回⽂件的。因此,采⽤共享内存的通信⽅式效率是⾮常⾼的。
共享内存实现机制
共享内存是通过把同⼀块内存分别映射到不同的进程空间中实现进程间通信。⽽共享内存本⾝不带任何互斥与同步机制,但当多个进程同时对同⼀内存进⾏读写操作时会破坏该内存的内容,所以,在实际中,同步与互斥机制需要⽤户来完成。
来看⼏个系统调⽤函数:
(1)创建共享内存
参数:key为输出型参数
size:size的⼤⼩应为1024整数倍(4k对齐)
shmflg:权限标志
(2)将共享内存映射到⾃⼰的内存空间:shmat
shmat是空间映射,通过创建的共享内存,在它能被进程访问之前,需要把该段内存映射到⽤户进程空间。shmaddr是⽤来指定共享内存映射到当前进程中的地址位置,要想改设置有⽤,shmflag必须设置为SHM_RND标志。⼤多情况下,应设置为空指针(void*)0,让系统⾃动选择地址,从⽽减⼩程序对硬件的依赖性。shmflag除了上⾯的设置外,还可以设置为
SHM_RDONLY,使得映射过来的地址只读。
返回值:调⽤成功则返回映射地址的第⼀个字节,失败返回-1。
(3)解除映射:shmdt
参数为要解除的地址空间。
(4)控制共享内存
先来看第三个参数的结构体:
第⼆个参数cmd的选项:IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构体复制到buf⾥
IPC_SET:改变共享内存的状态,把buf所指的结构体中的uid,gid,mode,复制到共享内存的shmid_ds结构体内IPC_RMID:删除这块共享内存
BUF:共此内存管理结构体
代码实现:
共享内存的特点:
(1)共享内存就是允许两个不想关的进程访问同⼀个内存
(2)共享内存是两个正在运⾏的进程之间共享和传递数据的最有效的⽅式
(3)不同进程之间共享的内存通常安排为同⼀段物理内存
(4)共享内存不提供任何互斥和同步机制,⼀般⽤信号量对临界资源进⾏保护。
(5)接⼝简单
进程间通信 共享内存所有进程间通信的特点:
(1)管道
管道分为命名管道和匿名管道。匿名管道只能单向通信,且只能在有亲缘关系的进程间使⽤,常⽤于⽗⼦进程,当⼀个进程创建了⼀个管道,并调⽤fork创建⼦进程后,⽗进程关闭读端,⼦进程关闭写端,实现单向通信。管道是⾯向字节流,⾃带互斥与同步机制,⽣命周期随进程。
命名管道与匿名管道:命名管道允许毫不相⼲的两个进程之间
(2)信号量
信号量是⼀个计数器,可以⽤来控制多个线程对共享资源的访问,它不是⽤于交换⼤批数据,⽽⽤于多线程之间的同步,常作为⼀种锁机制,防⽌某进程在访问资源时其他进程也来访问,因此,主要作为进程间以及同⼀进程的不同线程间的同步⼿段。
(3)消息队列
消息队列是消息的链表,存放在内核中并由消息队列标识符标识,消息队列克服了信号传递信息少,管道只能承载⽆格式字节流以及缓冲区受限等特点。消息队列是UNIX下不同进程之间可以实现资源共享的⼀种机制,UNIX允许不同进程将格式化的数据流以消息队列形式发送给任意进程,对消息队列具有操作权限的进程都可以使⽤msgget完成对消息队列的操作控制,通过使⽤消息类型,进程可以按顺序读信息,或为消息安排优先级顺序。
(4)共享内存
共享内存就是映射⼀段能被其他进程所访问的内存,这段共享内存由⼀个进程创建,但多个进程都可以访问,共享内存是最快的IPC⽅式,它是针对其他IPC⽅式运⾏效率低⽽专门设计的,它往往与其他机制,如信号量,配合使⽤,来实现进程间的同步。
以上就是Linux共享内存实现机制的内容详细介绍,⼤家可以参考下,如果有疑问的可以到本站留⾔,进⾏讨论。感谢阅读,希望能帮助到⼤家,谢谢⼤家对本站的⽀持!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。