共享内存的IPC原理
共享内存进程间通信机制主要用于实现进程间的大量数据传输。下图是使用共享内存实现进程间大量数据传输的示意图:
共享内存是内存中单独打开的内存空的一部分。这部分内存空有自己独特的数据结构,包括访问权限、大小和最新访问时间。数据结构定义如下:
from /usr/include/linux/shm.h
struct shmid_ds {
struct ipc _ perm shm _ perm/*操作许可操作权限*/
int shm _ segsz/*段大小(字节)段长度大小*/
_ _ kernel _ time _ t shm _ atime/*最后连接时间最晚连接时间*/
_ _ kernel _ time _ t shm _ dtime/*上次分离时间最近分离时间*/
_ _ kernel _ time _ t shm _ ctime/*上次更改时间上次更改时间*/
_ _ kernel _ ipc _ pid _ t shm _ cpid/*创建者的pid创建者的pid */
_ _ kernel _ ipc _ pid _ t shm _ lpid/*最后一个操作员的最新操作pid的pid */
无符号短shm _ nattch/*当前附件数量*/
无符号短shm _ unused/*兼容性*/
void * shm _ unused2/*同上-DIPC使用*/
void * shm _ unused3/*未使用*/|
};
在使用这个共享内存空之前,两个进程需要在进程地址空和共享内存空之间建立一个连接,即把共享内存空挂载到进程中。
系统对共享内存有以下限制:
#定义shmmax 0x2000000/*最大共享段大小(字节)最大共享段大小*/
#定义shmmin1/*最小共享段大小(字节)最小共享段大小*/
#定义SHMMNI 4096 /*全segs系统的最大数量*/
#定义SHMALL(SHMMAX/getpage size()*(SHMMNI/16))|
定义SHMSEG SHMMNI /*每个进程的最大共享segs数*/
Linux共享内存管理
1.创建共享内存
#include <。sys/ipc.h>。#include <。sys/shm.h>。
/*
*第一个参数是键值,通常由ftok()函数生成
*第二个参数是要创建的共享内存段的大小(以字节为单位)
*第三个参数用于标识共享内存段的创建标识符
*/
int shmget(key_t key,size_t size,int shmflg);
2.共享内存控制
#include <。sys/ipc.h>。#include <。sys/shm.h>。
/*
*第一个参数是要操作的共享内存标识符
*第二个参数是要执行的操作
*第三个参数是shmid_ds结构的临时共享内存变量信息
*/
int shmctl(int shmid,int cmd,struct shmid _ ds * buf);
3.映射共享内存对象
系统调用shmat()函数将一个共享内存段映射到调用进程的数据段,并返回memory 空之间的第一个地址。其功能说明如下:
#include <。sys/types.h>。
#include <。sys/shm.h>。
/*
*第一个参数是要操作的共享内存标识符
*第二个参数用于指定共享内存的映射地址。如果不是0,就是这个参数。如果它是0,它将由系统分配
*第三个参数用于指定共享内存段的访问权限和映射条件
*/
void *shmat(int shmid,const void *shmaddr,int shmflg);
4.分离共享内存对象
使用共享内存空后,需要使用shmdt()函数调用将其与当前进程分离。该函数声明如下:
#include <。sys/types.h>。
#include <。sys/shm.h>。
/*
*参数是分配的共享内存的第一个地址
*/
int shm dt(const void * shmaddr);
父进程和子进程之间存在共享内存
1.使用fork()函数创建子进程后,该进程将继承父进程装载的共享内存。
2.如果调用exec()执行一个新程序,所有装入的共享内存将自动卸载。
3.如果在某个进程中调用exit()函数,所有装入的共享内存都将从当前进程中断开。
程序实例
申请共享内存,父进程在第一个地址存储一个整数,子进程读出。
#包括
#include <。sys/ipc.h>。
#include <。sys/shm.h>。
#include <。sys/types.h>。
#包括
#包括
#定义SHM_SIZE 1024
int main()
{
int shm_id,pid
int * ptr = NULL
/*申请共享内存*/
shm_id = shmget((key_t)1004,SHM_SIZE,IPC _ CREAT | 0600);
/*将共享内存映射到进程地址空 */
ptr = (int*)shmat(shm_id,0,0);
printf("Attach addr为%p n ",ptr);
* ptr = 1004
printf(" Parent的值为:%d n ",* ptr);
if((pid=fork()) == -1){
perror(" fork Err ");
退出(0);
}
else if(!pid){
printf(" Child的值为:%d n ",* ptr);
退出(0);
}else{
睡眠(1);
/*取消映射*/
shm dt(ptr);
/*删除共享内存*/
shmctl(shm_id,IPC_RMID,0);
}
返回0;
}
输出结果:
1.《shm Linux 进程间如何共享内存?》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《shm Linux 进程间如何共享内存?》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/junshi/1232558.html