昆明网站建设问问q778925409耍強,个人摄影网站源码,wordpress文章列表显示,网络规划设计师希赛消息队列、共享内存、信号量的机制#xff1a;它们在使用之前都要生成 key#xff0c;然后通过 key 得到唯一的 id#xff0c;并且都是通过 xxxget 函数。在内核里面#xff0c;这三种进程间通信机制是使用统一的机制管理起来的#xff0c;都叫 ipcxxx。为了维护这三种进程…消息队列、共享内存、信号量的机制它们在使用之前都要生成 key然后通过 key 得到唯一的 id并且都是通过 xxxget 函数。在内核里面这三种进程间通信机制是使用统一的机制管理起来的都叫 ipcxxx。为了维护这三种进程间通信进制在内核里面我们声明了一个有三项的数组。
通过这段代码来具体看一看。
struct ipc_namespace {
......struct ipc_ids ids[3];
......
}#define IPC_SEM_IDS 0
#define IPC_MSG_IDS 1
#define IPC_SHM_IDS 2#define sem_ids(ns) ((ns)-ids[IPC_SEM_IDS])
#define msg_ids(ns) ((ns)-ids[IPC_MSG_IDS])
#define shm_ids(ns) ((ns)-ids[IPC_SHM_IDS])
根据代码中的定义第 0 项用于信号量第 1 项用于消息队列第 2 项用于共享内存分别可以通过 sem_ids、msg_ids、shm_ids 来访问。
这段代码里面有 ns全称叫 namespace。可能不容易理解你现在可以将它认为是将一台 Linux 服务器逻辑的隔离为多台 Linux 服务器的机制它背后的原理是一个相当大的话题我们需要在容器那一章详细讲述。现在你就可以简单的认为没有 namespace整个 Linux 在一个 namespace 下面那这些 ids 也是整个 Linux 只有一份。
共享内存的创建和映射过程。
调用 shmget 创建共享内存。先通过 ipc_findkey 在基数树中查找 key 对应的共享内存对象 shmid_kernel 是否已经被创建过如果已经被创建就会被查询出来例如 producer 创建过在 consumer 中就会查询出来。如果共享内存没有被创建过则调用 shm_ops 的 newseg 方法创建一个共享内存对象 shmid_kernel。例如在 producer 中就会新建。在 shmem 文件系统里面创建一个文件共享内存对象 shmid_kernel 指向这个文件这个文件用 struct file 表示我们姑且称它为 file1。调用 shmat将共享内存映射到虚拟地址空间。shm_obtain_object_check 先从基数树里面找到 shmid_kernel 对象。创建用于内存映射到文件的 file 和 shm_file_data这里的 struct file 我们姑且称为 file2。关联内存区域 vm_area_struct 和用于内存映射到文件的 file也即 file2调用 file2 的 mmap 函数。file2 的 mmap 函数 shm_mmap会调用 file1 的 mmap 函数 shmem_mmap设置 shm_file_data 和 vm_area_struct 的 vm_ops。内存映射完毕之后其实并没有真的分配物理内存当访问内存的时候会触发缺页异常 do_page_fault。vm_area_struct 的 vm_ops 的 shm_fault 会调用 shm_file_data 的 vm_ops 的 shmem_fault。在 page cache 中找一个空闲页或者创建一个空闲页。 此文章为11月Day21学习笔记内容来源于极客时间《趣谈Linux操作系统》推荐该课程。