文章目录
- 一、什么是共享内存
- (一)共享内存的定义
- (二)共享内存的原理
- (三)共享内存的理解
- 二、为什么要有共享内存
- 三、共享内存怎么进行
- (一) 共享内存的数据结构
- (二)共享内存的函数
- 1.shmget函数
- 2.shmat函数
- 3.shmdt函数
- 4.shmctl函数
- 四、共享内存例子——代码
- 五、共享内存的优缺点
- (一)优点
- (二)缺点
一、什么是共享内存
(一)共享内存的定义
-
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。
-
共享内存是一种用于实现进程间通信(IPC)的方法,不同进程通过访问同一块内存区域实现数据共享和交互。每个进程可以将自身的虚拟地址映射到物理内存中的特定区域,当不同进程将相同的物理内存区域与各自的虚拟地址空间关联时,这些进程就能实现通过共享内存来完成IPC。若某进程更改了共享内存区的内容,其它进程都会觉察到该区域的更改。
(二)共享内存的原理
进程间通信的本质——不同的进程看到同一份资源
每个进程有自己的进程控制块和地址空间,且都有一个与之对应的页表,负责将进程的虚拟地址与物理地址进行映射,通过内存管理单元(MMU)进行管理。两个不同的虚拟地址通过页表映射到物理空间的同一区域,它们所指向的这块区域即共享内存。
(三)共享内存的理解
- 进程间通信是专门设计的,用来ipc
- 共享内存是一种通信方式,所有想通信的人都可以用
- 系统中一定会同时存在许多的共享内存
二、为什么要有共享内存
通过让不同的进程,看到同一个进程内存的方式。
三、共享内存怎么进行
(一) 共享内存的数据结构
struct shmid_ds {
struct ipc_perm shm_perm; /* operation perms */
int shm_segsz; /* size of segment (bytes) */
__kernel_time_t shm_atime; /* last attach time */
__kernel_time_t shm_dtime; /* last detach time */
__kernel_time_t shm_ctime; /* last change time */
__kernel_ipc_pid_t shm_cpid; /* pid of creator */
__kernel_ipc_pid_t shm_lpid; /* pid of last operator */
unsigned short shm_nattch; /* no. of current attaches */
unsigned short shm_unused; /* compatibility */
void *shm_unused2; /* ditto - used by DIPC */
void *shm_unused3; /* unused */
};
(二)共享内存的函数
1.shmget函数
功能:用来创建共享内存
原型 int shmget(key_t key, size_t size, int shmflg);
参数:
key:这个共享内存段名字 size:共享内存大小
shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1
2.shmat函数
功能:将共享内存段连接到进程地址空间
原型 void *shmat(int shmid, const void *shmaddr, int
shmflg);
参数 :
shmid: 共享内存标识 shmaddr:指定连接的地址
shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY 返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1
注意:
shmaddr为NULL,核心自动选择一个地址
shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr -
(shmaddr % SHMLBA) shmflg=SHM_RDONLY,表示连接操作用来只读共享内存
3.shmdt函数
功能:将共享内存段与当前进程脱离
原型:
int shmdt(const void *shmaddr);
参数
shmaddr: 由shmat所返回的指针 返回值:成功返回0;失败返回-1
注意:
将共享内存段与当前进程脱离不等于删除共享内存段
4.shmctl函数
功能:用于控制共享内存
原型:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
shmid:由shmget返回的共享内存标识码 cmd:将要采取的动作(有三个可取值)
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构 返回值:成功返回0;失败返回-1
四、共享内存例子——代码
五、共享内存的优缺点
(一)优点
所以共享内存是所有进程间通信方式中最快的一种通信方式,因为该通信方式需要进行的拷贝次数最少。
(二)缺点
但是共享内存也是有缺点的,我们知道管道是自带同步与互斥机制的,但是共享内存并没有提供任何的保护机制,包括同步与互斥。