System V IPC共享内存

相关数据结构

struct ipc_namespace

                 

新建IPC对象:shmget()

1.如果找不到相同键值对应的IPC资源,并且要求新建IPC对象

2.Shmget()中第一个参数,键值key == IPC_PRIVATE都会新建一个IPC对象

新建IPC对象的过程:

系统调用sys_shmget()调用ipcget()完成通过键值查找或者新建IPC资源标识符的工作。

ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params)

其中:

(1)ns来自ns = current->nsproxy->ipc_ns;

(2)&shm_ids(ns)对应一个宏,指向ipc_ids对象(这里就是共享内存)的指针

(3)shm_ops,操作函数

(4)Shm_params来自用户传来的信息。

在ipcget()中调用ipcget_new或者ipcget_public函数

1)预分配,查看存储空间是否足够(避免做了一系列处理后,由于资源不足而失败。)

先通过err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);来预分配IPC对象,如果还有足够的存储资源供IPC资源使用,就返回1(之后就来真正的新建IPC资源),如果资源不足,就返回0(此时函数shmget()结束,返回错误码:ENOMEN,没有足够的存储资源)

(2)调用newseg()函数来新建IPC资源。这个函数的返回值就是IPC资源标识符 

第一步.首先新建相关资源,特殊文件等等。即shmid_kernel的一个实体。这个实体中有第一个成员就是kern_ipc_perm成员,它主要是装载着键值和进程的一些信息及权限等内容 。

struct kern_ipc_perm

{

spinlock_t lock;

int deleted;

intid; //IPC资源标识符

key_tkey; //魔数,

uid_t uid;

gid_t gid;

uid_t cuid;

gid_t cgid;

umode_t mode; 

unsigned longseq;// 序数

void *security;

};

第二步,通过IDR机制,把这个kern_ipc_perm实例的指针关联到一个整数上去。这个整数就是内核内部ID。每个内核内部ID都会关联到相应的kern_ipc_perm实例上。

在newseg()函数中调用id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);

Ipc_addid()完成的工作是通过IDR机制把新建的kern_ipc_perm和一个内核ID做关联,然后用过 ipc_buildid(id, new->seq)函数来把生成一个唯一的IPC资源标志符,把这个标识符放到&shp->shm_perm中的id成员里去。


在newseg()中

struct shmid_kernel *shp;

//shmid_kernel结构的第一个成员shm_perm就是kern_ipc_perm

shp->shm_perm.key = key;

id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);

//在这个函数中,会把IPC资源标识符填到shp->shm_perm->id中去。

第三步 对于共享内存,还要file->f_dentry->d_inode->i_ino = shp->shm_perm.id;


查找key对应的IPC资源标志符:

因为Shmget()中第一个参数,键值key = IPC_PRIVATE。所以我们要先来查找是不是有这个key值对应的IPC资源。

ipcget()ipcget_public()中调用

struct kern_ipc_perm *ipcp; 

ipcp = ipc_findkey(ids, params->key);

在ipc_findkey中调用idr_find(&ids->ipcs_idr, next_id);

//使用IDR机制,返回一个kern_ipc_perm的对象。这个对象包含有IPC资源标志符。

shmget的过程图:

关于新建IPC资源对象中

(1)shmid_kernel中除了kern_ipc_perm外,还有一个重要的成员struct *file shm_file这个数据结构是内核用来描述共享内存专用的。这个指针是为了把共享内存以文件映射的方式与进程关联的。 

它存放文件对象的地址。每个IPC共享内存区与属于shm的特殊文件系统的一个普通文件相关联。

因为shm文件系统在系统目录树中没有安装点,因此,用户不能通过普通的VFS系统调用打开并访问它的文件。但是,只要进程“附加”(shmat())一个内存段,内核就调用do_nmap(),并在进程的地址空间中创建文件的一个新的共享内存映射。

IPC共享内存对应的内存区是用vm_area_struct对象描述的。它的vm_file字段指回特殊文件的文件对象,而特殊文件又依次引用目录项对象(struct dentry)和索引节点对象(struct inode)。存放在索引节点的i_ino字段的索引节点号实际上是IPC共享内存区的内核内部ID,因此,索引节点对象间接引用shmid_kernel描述符。

对于任何共享内存映射,通过address_space对象把页框包含在页高速缓存中,而address_space对象包含在索引节点中,而且被索引节点的i_mapping字段引用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值