首页 > 编程知识 正文

shmget函数创建共享内存,使用shmget函数来创建共享内存

时间:2023-05-06 00:26:51 阅读:264674 作者:3880

共享内存区域是被多个进程共享的一部分物理内存;如果多个进程都把该内存区域映射到自身的虚拟地址空间,则这些进程都可以直接访问该共享内存区域,从而可以通过该区域进行通信。

共享内存是进程间共享数据最快的一种方法,一个进程向共享内存区域写入了数据,共享这个内存区域所有进程就可以立刻查看到其中的内容;这快共享虚拟内存的页面,出现在每一个共享该页面的进程的页表中;但是它不需要在所有的进程的虚拟内存中都有相同的虚拟地址。

如下图所示:

像所有的System V IPC对象一样,对于共享内存的获取是由Key控制。内存共享之后,对进程如何使用这块内存就不再做检查。它们必须依赖于其他机制。

每一个新创建的共享内存对象都有一个shmid_kernel数据结构来表达,系统中所有的shmid_kernel数据结构都保存在shm_segs向量表中,该向量表的每一个元素都是一个指向shmid_kernel数据结构的指针。

shm_segs向量表的定义如下:

struct shmid_kernel *shm_segs【SHMMNI】;其中SHMMNI为128,表示系统中最多有128个共享内存对象。

数据结构如下:

struct shmid_kernel

struct shmid_ds u;

unsigned long shm_npages;

unsigned long *shm_pages;

struct vm_area_struct *attaches;

};

其中:

shm_pages代表该共享内存对象所占据的内存页面组数,组数里面的每一个元素当然是每个内存页面的起始地址。

shm_npages则是该共享内存对象占用内存页面的个数,以页为单位,这个数量涵盖了申请空间的最小倍数。

shmid_ds是一个数据结构,描述了该共享内存区的认证信息,其结构如下:

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;

_kernel_ipc_pid_t shm_lpid;

unsigned short shm_nattch;

unsigned short shm_unused;

void *shm_unused2;

void *shm_unused3;

};

attaches 描述被该共享的物理内存对象所映射的各个进程的虚拟内存区域。

Linux共享内存提供了4种操作:

1.共享内存对象的创建

int sys_shmget(key_t key,int size,int shmflg);

这里的key表示该共享内存对象的键值,size是该共享内存大小以字节为单位,shmflg是标志。

它所做的工作如下:

1)如果key==IPC_PRIVATE,则总是会创建一个新的共享内存对象。

2)在向量表shm_segs中查找键值key的共享内存对象,确认其合法性

2.关联,在创建某个共享内存区域的标识符后,还必须将共享内存区域映射到进程的虚拟地址空间,然后才能使用该共享内存区域,系统调用sys_ipc(call值SHMAT)用于共享内存区域到进程虚拟地址空间的映射,而真正完成动作的函数是sys_shmat,其定义如下:

void *shmat(int shmid,const void *shmaddr,int shmflg);

其所做的工作是:

1)根据shmid找到共享内存对象

2)如果shmaddr为0,即用户没有指定该共享内存区域在它的虚拟空间中的位置,则由系统在进程的虚拟地址空间中为其找一块区域,否则就用shmaddr作为映射的虚拟地址。

3)检查虚拟地址的合法性

4)认证检查

5)申请一块内存用于建立数据结构vm_area_struct,填写该结构

6)检查该内存区域,将其加入到进程mm结构和该共享内存对象的vm_area_struct队列中

3.分离,当进程不再需要共享虚拟内存的时候,它们与之分离;系统调用sys_ipc(call 值为shmdt)用于该共享内存与进程虚拟地址空间的分离,而真正完成分离动作的函数是 int sys_shmdt(char *shmaddr);

4.控制,Linux在共享内存上实现第四种操作是共享内存控制,其由函数sys_shmctl实现;共享内存提供了一种快速灵活的机制,它允许进程之间直接共享大量数据,而无需拷贝使用或系统调用。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。