共享内存:
是所有进程间通信最快的一种,因为共享内存直接通过虚拟地址映射访问物理内存,而其他方式因为都是内核中的缓冲区,因此通信时都会涉及用户态与内核态之间的两次数据拷贝。因此通信速度最快。
为什么最快?(从各个进程间通信方式的原理说起)
少了两次数据内存拷贝 内核-》用户-》内核
共享内存的原理
通过将同一块内存映射到自己的虚拟地址空间,实现对相同的一块物理内存进行操作,通过这种方式实现多个进程间的数据共享功能,因为共享内存是直接通过虚拟地址操作内存实现共享,相较于其他方式,少了两步用户态、内核态之间的数据拷贝过程,因此速度最快。(都有自己的虚拟地址空间,但是映射到了同一块内存)
共享内存的操作步骤:
1)创建共享内存 (开辟物理内存–具有标识符) int shmget(key_t key,int size,int flag)
key:共享内存的的标识符,多个进程通过相同的标识符可以打开同一块共享内存,这个可以自己随便设定,也有一个接口key_t ftok()
size:共享内存大小
flag:IPC_CREAT|IPC_EXCL|权限
返回值:成功返回一个操作句柄,失败返回-1
2)将共享内存映射到虚拟地址空间 shmat()
void shmat(int shmid,void addr)
shmid:共享内存操作句柄
addr:映射到虚拟地址空间的首地址,通常置NULL
Flag:通常置0—可读可写 SHM_RDONLY–只读
返回值:成功:返回映射的虚拟空间首地址 失败返回-1
3)直接对这块内存进行操作 memcpy()
4)解除映射关系 shmdt()
Int shmdt(void* shmstart)
Shmatart:映射到虚拟地址空间的首地址
返回值:成功返回0 失败-1
5)删除共享关系 shmctl() 链接数为0的时候才会真正的删除
删除共享内存的时候,共享内存并不会立即被解除(因为可能会造成正在访问的进程崩溃),而是将key修改为0,表示这块共享内存将不会继续接收映射连接,当这块共享内存的映射连接数为0时,则自动被释放。
Int shmctl(int shmid,int cmd,struct shmid_ds *buf)
Shmid:操作句柄
Cmd:具体对共享内存要进行的操作—IPC_RMID—删除共享内存
Buf:里头存的一些信息,什么最后一次修改时间呀,多少个与这个共享内存建立连接等。
返回值:成功0 失败-1
代码:
Shm.c
Shmget(key_t key,size_t size,int shmflg)
Key: 共享内存标识符
Size: 共享内存大小
Shmflg:选项标志
IPC_CREAT:共享内存不存在则创建,存在则打开
IPC_EXCL:与IPC_CREAT同用,则共享内存存在时报错
Shm_mode:权限
返回值:标识符(代码中的操作句柄)失败-1
Ipcs -m 共享代码段
进程间通信方式的查看
ipcs [-m -s -q]
-m 查看共享内存
-q 查看消息对列
-s 查看信号量