在SMP系统中 , 每个进程的task_struct结构中包含着当前运行它的处理器的编号以及上次运行时处理器的编号 。把进程每次都调度到不同CPU上执行显然毫无意义 , Linux可以使用processor_mask来使得某个进程只在一个或者几个处理器上运行:如果N位置位 , 则进程可在处理器N上运行 。当调度管理器选择新进程运行时 , 它 不会考虑一个在其processor_mask中在当前处理器位没有置位的进程 。同时调度管理器将给予上次在此处理器中运行的进程一些优先权 , 因为将进程迁移到另外处理器上运行将带来性能的损失 。
4.4文件
图4.1 进程所使用的文件
图4.1给出了两个描叙系统中每个进程所使用的文件系统相关信息 。第一个fs_struct包含了指向进程的VFS inode和其屏蔽码 。这个屏蔽码值是创建新文件时所使用的缺省值 , 可以通过系统调用来改变 。
第二个数据结构files_struct包含了进程当前所使用的所有文件的信息 。程序从标准输入中读取并写入到标准输出中去 。任何错误信息将输出到标准错误输出 。这些文件有些可能是真正的文件 , 有的则是输出/输入终端或者物理设备 , 但程序都将它们视为文件 。每个文件有一个描叙符 , files_struct最多可以包含256个文件数据结构 , 它们分别描叙一个被当前进程使用的文件 。f_mode域表示文件将以何种模式创建:只读 、读写还是只写 。f_pos中包含下一次文件读写操作开始位置 。f_inode指向描叙此文件的VFS inode , f_ops指向一组可以对此文件进行操作的函数入口地址指针数组 。这些抽象接口十分强大 , 它们使得Linux 能够支持多种文件类型 。在Linux中 , 管道是用我们下面要讨论的机制实现的 。
每当打开一个文件时 , 位于files_struct中的一个空闲文件指针将被用来指向这个新的文件结构 。Linux进 程希望在进程启动时至少有三个文件描叙符被打开 , 它们是标准输入 , 标准输出和标准错误输出 , 一般进程 会从父进程中继承它们 。这些描叙符用来索引进程的fd数组 , 所以标准输入 , 标准输出和标准错误输出分别 对应文件描叙符0 , 1和2 。每次对文件的存取都要通过文件数据结构中的文件操作子程序和VFS inode一起来完成 ,
4.5虚拟内存
进程的虚拟内存包括可执行代码和多个资源数据 。首先加载的是程序映象 , 例如ls 。ls和所有可执行映象一样 , 是由可执行代码和数据组成的 。此映象文件包含所有加载可执行代码所需的信息 , 同时还将程序数据连接进入进程的虚拟内存空间 。然后在执行过程中 , 进程定位可以使用的虚拟内存 , 以包含正在读取的文件内容 。新分配的虚拟内存必须连接到进程已存在的虚拟内存中才能够使用 。最后Linux进程调用通用库过程 , 比如文件处理子程序 。如果每个进程都有库过程的拷贝 , 那么共享就变得没有意义 。而Linux可以使多个进程同时使用共享库 。来自共享库的代码和数据必须连接进入进程的虚拟地址空间以及共享此库的其它进程的虚拟地址空间 。
任何时候进程都不同时使用包含在其虚拟内存中的所有代码和数据 。虽然它可以加载在特定情况下使用的那些代码 , 如初始化或者处理特殊事件时 , 另外它也使用了共享库的部分子程序 。但如果将这些没有或很少使用的代码和数据全部加载到物理内存中引起极大的浪费 。如果系统中多个进程都浪费这么多资源 , 则会大大降低的系统效率 。Linux使用请求调页技术来把那些进程需要访问的虚拟内存带入物理内存中 。核心将进程页表中这些虚拟地址标记成存在但不在内存中的状态 , 而无需将所有代码和数据直接调入物理内存 。当进程试图访问这些代码和数据时 , 系统硬件将产生页面错误并将控制转移到Linux核心来处理之 。这样对于处理器地址空间中的每个虚拟内存区域 , Linux都必须知道这些虚拟内存从何处而来以及如何将其载入内存以处理页面错误 。
推荐阅读
- 网卡设置指南
- Linux下构架qmail邮件系统
- linux的运行模式:runlevel
- 用 Linux 打造路由器
- Linux 和 Windows 共享交换区
- Linux下的常用软件列表
- 优化Linux系统硬盘的七个实用技巧
- Linux系统中提取DVD音频的方法介绍
- 在Linux中如何提高文件系统的使用效率
- Slackware EyooLinux服务器配置相关指令