象正常退出一样 , 当进程被删除时 , Linux将遍历该进程的sem_undo集合对信号灯数组使用调整值 。如果信号灯集合被删除而sem_undo数据结构还在进程的task_struct结构中则此信号灯数组标志符将被置为无效 。此时 信号灯清除代码只需丢弃sem_undo结构即可 。
5.3.4共享内存
共享内存允许一个或多个进程通过同时出现在它们虚拟地址空间中的内存来通讯 。此虚拟内存的页面出现在每个共享进程页表中 。但此页面并不一定位于所有共享进程虚拟内存的相同位置 。和其它系统V IPC对象的使用方法一样 , 对共享内存区域的访问是通过键和访问权限检验来控制的 。一旦内存被共享 , 则再不会检验进程对对象的使用方式 。它依赖于其它机制 , 如系统V信号灯 , 来同步对共享内存的访问 。
图5.4 系统V IPC共享内存
每个新创建的共享内存区域由一个shmid_ds数据结构来表示 。它们被保存再shm_segs数组中 。shmid_ds数据结构描叙共享内存的大小 , 进程如何使用以及共享内存映射到其各自地址空间的方式 。由共享内存创建者控制对此内存的存取权限以及其键是公有还是私有 。如果它由足够权限 , 它还可以将此共享内存加载到物理内存中 。
每个使用此共享内存的进程必须通过系统调用将其连接到虚拟内存上 。这时进程创建新的vm_area_struct来描叙此共享内存 。进程可以决定此共享内存在其虚拟地址空间的位置 , 或者让Linux选择一块足够大的区域 。新的vm_area_struct结构将被放到由shmid_ds指向的vm_area_struct链表中 。通过vm_next_shared和vm_prev_shared 指针将它们连接起来 。虚拟内存在连接时并没有创建;进程访问它时才创建 。
当进程首次访问共享虚拟内存中的页面时将产生页面错 。当取回此页面后 , Linux找到了描叙此页面的vm_area_struct数据结构 。它包含指向使用此种类型虚拟内存的处理函数地址指针 。共享内存页面错误处理 代码将在此shmid_ds对应的页表入口链表中寻找是否存在此共享虚拟内存页面 。如果不存在 , 则它将分配物理页面并为其创建页表入口 。同时还将它放入当前进程的页表中 , 此入口被保存在shmid_ds结构中 。这意味着下个试图访问此内存的进程还会产生页面错误 , 共享内存错误处理函数将为此进程使用其新创建的物理页面 。这样 , 第一个访问虚拟内存页面的进程创建这块内存 , 随后的进程把此页面加入到各自的虚拟地址空间中 。
当进程不再共享此虚拟内存时 , 进程和共享内存的连接将被断开 。如果其它进程还在使用这个内存 , 则此操作只影响当前进程 。其对应的vm_area_struct结构将从shmid_ds结构中删除并回收 。当前进程对应此共享内存地址的页表入口也将被更新并置为无效 。当最后一个进程断开与共享内存的连接时 , 当前位于物理内存中的共享内存页面将被释放 , 同时还有此共享内存的shmid_ds结构 。
当共享内存没有被锁入物理内存时 , 情况将更加复杂 。此时共享内存页面可能会在内存使用高峰期 , 被交换到系统的交换磁盘上 。共享内存如何被交换与调入物理内存将在mm一章中详细描叙 。
推荐阅读
- Linux 核心--5.Linux进程
- 网卡设置指南
- Linux下构架qmail邮件系统
- linux的运行模式:runlevel
- 用 Linux 打造路由器
- Linux 和 Windows 共享交换区
- Linux下的常用软件列表
- 优化Linux系统硬盘的七个实用技巧
- Linux系统中提取DVD音频的方法介绍
- 在Linux中如何提高文件系统的使用效率
