Linux教程(第4版)习题答案第1

您所在的位置:网站首页 请求分页技术的基本思想是什么 Linux教程(第4版)习题答案第1

Linux教程(第4版)习题答案第1

2024-07-17 04:38| 来源: 网络整理| 查看: 265

思考题5 5.1 说明Linux系统的体系结构分为哪几层。 答:Linux系统的体系结构大致可分为三层: ① 靠近硬件的底层是内核,即Linux操作系统常驻内存部分。 ② 中间层是内核之外的shell层,即操作系统的系统程序部分。 ③ 最高层是应用层,即用户程序部分。 5.2 说明Linux系统核心结构的组成情况。 答:Linux是采用单体结构的操作系统,所有的内核系统功能都包含在一个大型的内核软件之中。Linux内核分为用户层、核心层和硬件层3个层次,其内核结构框图如下图所示。

5.3 什么是进程?什么是线程?Linux系统中的进程有哪些状态?如何获取系统中各进程的状态? 答:简单地说,进程就是程序的一次执行过程。具体地说,进程是具有独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。 线程(Thread)是进程中实施调度和分派的基本单位。 在Linux系统中,进程有五种状态:①运行态(TASK_RUNNING)。②可中断等待态(TASK_INTERRUPTIBLE)。③不可中断等待态(TASK_UNINTERRUPTIBLE)。④停止态(TASK_STOPPED)。⑤僵死态(TASK_ZOMBIE)。 利用命令ps aux可以获取系统中各进程的状态。 5.4 Linux系统中进程有哪两种模式?各有何特点? 答:Linux系统中进程的运行模式划分为用户模式和内核模式。 在内核模式下运行的进程可以执行机器的特权指令,该进程的运行不受用户的干预,即使是root用户也不能干预内核模式下进程的运行。 用户模式中执行的进程,可以通过系统调用或在出现中断、异常时进入内核模式。 5.5 Linux系统中进程控制块的作用是什么?它与进程有何关系? 答:Linux系统中的每个进程都有一个名为task_struct的数据结构,它相当于“进程控制块”,包含了进程的描述信息和控制信息,是进程组成中最关键的部分。 每个进程有唯一的进程控制块;操作系统根据它对进程实施控制和管理,是进程存在的唯一标志。 5.6 Linux系统如何执行进程调度? 答:Linux系统的进程调度涉及调度方式、调度策略和调度时机三个方面。 Linux内核的调度方式基本上采用“抢占式优先级”方式。 Linux系统针对不同类别的进程提供了三种不同的调度策略,即: SCHED_FIFO(适合于实时进程)、SCHED_RR(对应“时间片轮转法”)以及SCHED_OTHER(适合于交互式的分时进程)。 核心进行进程调度的时机有以下几种情况: (1)当前进程调用系统调用nanosleep()或者pause(),使自己进入睡眠状态,主动让出一段时间的CPU使用权; (2)进程终止,永久地放弃对CPU的使用; (3)在时钟中断处理程序执行过程中,发现当前进程连续运行的时间过长; (4)当唤醒一个睡眠进程时,发现被唤醒的进程比当前进程更有资格运行; (5)一个进程通过执行系统调用来改变调度策略或者降低自身的优先权,从而引起立即调度。 5.7 shell的基本工作过程是怎样的? 答:shell命令解释程序不属于内核部分,而是在核心之外,以用户态方式运行。其基本工作流程是: ① 读取用户由键盘输入的命令行。 ② 判断命令是否正确,且将命令行的其他参数改造为系统调用execve( )内部处理所要求的形式。 ③ 终端进程调用fork( )建立一个子进程。 ④ 终端进程本身用系统调用wait4( )来等待子进程完成(如果是后台命令,则不等待)。 ⑤ 当调度子进程运行时,它调用execve( )—— 根据文件名(即命令名)到目录中查找有关文件(可执行文件),调入内存,更换自己的映像,然后执行这个程序(即执行这条命令)。 ⑥ 如果命令行末尾有&(后台命令符号),则终端进程不执行系统调用wait4( ),而是立即发提示符KaTeX parse error: Expected 'EOF', got '&' at position 24: …个命令,转①;如果命令末尾没有&?,则终端进程要一直等待。当子进…,让用户输入新的命令,重复上述处理过程。 5.8 Linux系统一般采用哪种文件系统?其构造形式如何? 答:目前,Linux主要使用的文件系统是ext2和ext3。ext3是ext2的升级版本,加入了记录数据的日志功能。 ext2文件系统中的文件信息都保存在数据块中。ext2文件系统将逻辑块划分成块组,每个块组重复保存着一些有关整个文件系统的关键信息以及实际的文件和目录的数据块。Ext2文件系统的物理构造形式如下图所示 5.9 什么是块组?什么是超级块?超级块的功能是什么? 答: Linux主要使用的文件系统是ext2和ext3,各自划分成若干块组。每个块组重复保存着一些有关整个文件系统的关键信息,以及真正的文件和目录的数据块,其中包含超级块、块组描述结构、块位示图、索引节点位示图、索引节点表和数据块。 超级块位于每个块组的最前面,其中包含有关该文件系统的全部关键参数。当计算机加电进行引导或第1次遇到该文件系统时,就把超级块中的信息读入内存。超级块中包含标识文件系统类型的幻数、文件系统中的盘块数量、修改标记及其他关键管理信息。 超级块中包含有文件系统本身的大小和形式的基本信息,文件系统管理员可以利用这些信息来使用和维护文件系统。 5.10 什么是索引节点?索引节点主要有哪些内容?它与文件有何关系? 答:索引节点又被称为I节点,是一个结构数组,其中包含有关该文件的全部管理信息。 索引节点主要包括以下内容: 文件模式,文件属主信息,文件大小,时间戳,文件链接计数,数据块索引表等。 ext2文件系统的索引节点起着文件控制块的作用,利用这种数据结构可对文件进行控制和管理。每个文件都只有一个索引节点。 5.11 为什么要设立虚拟文件系统(VFS)?它与实际文件系统的关系是怎样的? 答:Linux系统可以支持多种文件系统,为此,必须使用一种统一的接口,这就是虚拟文件系统(VFS)。通过VFS将不同文件系统的实现细节隐藏起来,从外部看上去所有的文件系统都是一样的。 VFS是建立在具体文件系统之上的,VFS必须管理所有的文件系统。用户程序(进程)通过有关文件系统操作的系统调用进入系统空间,然后经由VFS才可使用Linux系统中具体的文件系统。 5.12 Linux系统通常为什么要把硬盘划分为多个文件系统?简述文件系统安装的基本过程。 答:一个硬盘上可以同时存在多个文件系统,每个文件系统占据硬盘的一个独立分区。Linux文件系统可以根据需要随时装卸,从而实现文件存储空间的动态扩充和信息安全。在系统初启时,只有根文件系统,其他的文件系统可以根据需要作为子系统动态地安装到主系统中,已安装的子文件系统也可从整个文件系统上卸下来,恢复安装前的独立状态。 文件系统安装的基本过程是:超级用户可以使用命令mount将新文件系统安装到主文件系统中。该命令带有3个主要参数:要安装的文件系统类型、该文件系统所在分区名和安装新文件系统的路径名(即安装点)。执行该命令时,Linux系统内核必须首先检查有关参数的有效性。VFS首先应找到要安装的文件系统,通过查找由file_systems指针指向的链表中的每一个file_system_type数据结构来搜索已知的文件系统(该结构包含文件系统的名字和指向VFS超级块读取程序地址的指针),当找到一个匹配的名字时,就可以得到读取文件系统超级块的程序的地址。接着要查找作为新文件系统安装点的VFS索引节点,并且在同一目录下不能安装多个文件系统。VFS安装程序必须分配一个VFS超级块(super_block),并且向它传递一些有关文件系统安装的信息。申请一个vfsmount数据结构(其中包括存储文件系统的块设备的设备号、文件系统安装的目录和一个指向文件系统的VFS超级块的指针),并使它的指针指向所分配的VFS超级块。当文件系统安装以后,该文件系统的根索引节点就一直保存在VFS索引节点缓存中。 5.13 Linux系统采用哪两种内存管理技术?各自的基本实现思想是什么? 答:Linux系统采用交换和请求分页两种内存管理技术。 请求分页存储管理技术是在简单分页存储技术基础上发展起来的,它的基本思想是:当进程运行时,不必把整个进程映像都放在内存中,只需在内存保留当前用到的那一部分页面。当进程访问到某些尚未在内存的页面时,就由核心把这些页面装入内存。这种策略使进程的虚拟地址空间映射到机器的物理空间时具有更大的灵活性,通常允许进程的大小可大于可用内存的总量,并允许更多进程同时在内存中执行。 内存交换的基本思想是:当系统中出现内存不足时,Linux内存管理子系统就释放一些内存页,从而增加系统中空闲内存页的数量,此任务是由内核的交换守护进程kswapd完成的。 5.14 何谓虚拟存储器?Linux系统如何支持虚存? 答:所谓虚拟存储器是用户能作为可编址内存对待的虚拟存储空间,它使用户逻辑存储器与物理存储器分离,是操作系统给用户提供的一个比真实内存空间大得多的地址空间。 Linux存储管理采用请求分页技术,请求分页提供虚拟存储器。它的基本思想是: 当我们要执行一个程序时才把它换入内存; 但并不把全部程序都换入内存,而是用到哪一页时才换入它。这样,就减少了对换时间和所需内存数量,允许增加程序的道数。 5.15 Linux系统中交换空间为何采用连续空间? 答:因为进程使用交换空间是临时性的,速度是关键性问题,系统一次进行多个盘块I/O传输比每次一块、多次传输的速度要快,所以核心在交换设备上是分配一片连续空间,而不管碎片的问题。 5.16 Linux为什么要采用三级页表?该机制如何工作? 答:现在地址码通常采用32位,这样,每个进程的虚拟存储空间可达4 GB。而Linux系统中页面的大小为4KB,因此进程虚拟存储空间要划分为220(1M)个页面。如果直接用页表描述这种映射关系,那么每个进程的页表就要有220(1M)个表项。很显然,用大量的内存资源来存放页表是不可取的。为此,Linux系统采用三级页表的方式。 Linux系统三级页表地址映射如下图所示。

图中PGD表示页面目录,PMD表示中间目录,PT表示页表。一个线性虚拟地址在逻辑上划分成4个位段,从高位到低位分别用做检索页面目录PGD的下标、中间目录PMD的下标、页表PT的下标和物理页面(即内存块)内的位移。把一个线性地址映射成物理地址分为以下4步: ① 以线性地址中最高位段作为下标,在PGD中找到相应的表项,该表项指向相应的PMD。 ② 以线性地址中第2个位段作为下标,在PMD中找到相应的表项,该表项指向相应的PT。 ③ 以线性地址中第3个位段作为下标,在PT中找到相应的表项,该表项指向相应的物理页面(即该物理页面的起始地址)。 ④ 线性地址中的最低位段是物理页面内的相对位移量,此位移量与该物理页面的起始地址相加就得到相应的物理地址。 5.17 Linux信号机制是如何实现进程通信的? 答:信号机制是在软件层次上对中断机制的一种模拟。异步进程可以通过彼此发送信号来实现简单通信。系统预先规定若干个不同类型的信号,各表示发生了不同的事件,每个信号对应一个编号。运行进程当遇到相应事件或者出现特定要求时,就把一个信号写到相应进程task_struct结构的signal位图中。接收信号的进程在运行过程中要检测自身是否收到了信号,如果已收到信号,则转去执行预先规定好的信号处理程序。处理之后,再返回原先正在执行的程序。 5.18 管道文件如何实现两个进程间的通信? 答:管道文件是连接两个命令的一个打开文件。一个命令向该文件中写入数据,称作写者;另一个命令从该文件中读出数据,称作读者。系统自动处理二者之间的同步、调度和缓冲。利用管道文件可以实现两个或多个进程间的直接通信。 5.19 Linux系统中设备驱动分层结构是怎样的?如何实现与设备的无关性? 答:设备驱动的分层结构自顶向下依次为:应用层、文件系统层、设备驱动层、物理设备层。 Linux系统采用设备文件统一管理硬件设备,从而将硬件设备的特性及管理细节对用户隐藏起来,实现用户程序与设备无关性。 5.20 Linux系统中可安装模块的思想是什么? 答:可安装模块是可以在系统运行时动态地安装和拆卸的内核模块。利用这个机制,可以根据需要在不必对内核重新编译连接的条件下,将可安装模块动态插入运行中的内核,成为其中一个有机组成部分; 或者从内核卸载已安装的模块。设备驱动程序或者与设备驱动紧密相关的部分(如文件系统) 都是利用可安装模块实现的。 5.21 什么是中断?中断的一般处理过程是什么? 答:所谓中断是指CPU对系统发生的某个事件作出的一种反应——CPU暂停正在执行的程序,保留现场后自动地执行相应的处理程序,处理完该事件后,如被中断进程的优先级最高,则返回断点继续执行被“打断”的程序。 中断的一般处理过程:保存被中断程序的现场,分析中断原因,转入相应处理程序进行处理,恢复被中断程序现场(即中断返回)。 5.22 Linux系统怎样处理系统调用? 答:Linux的系统调用是通过中断指令INT 0x80实现的。当CPU执行到中断指令INT 0x80时,硬件就作出一系列响应,其动作与中断响应相同。CPU穿过陷阱门,从用户空间进入系统空间。相应地,进程的上下文从用户堆栈切换到系统堆栈。接着运行内核函数system_call()。首先,进一步保存各寄存器的内容;接着调用syscall_trace(),以系统调用号为下标检索系统调用入口表sys_call_table,从中找到相应的函数; 然后,转去执行该函数,完成具体的服务。执行完服务程序,核心检查是否发生错误,并作相应处理。如果本进程收到信号,则对信号作相应处理。最后进程从系统空间返回到用户空间。

思考题6 6.1 gcc编译过程一般分为哪几个阶段?各阶段的主要工作是什么? 答:gcc编译过程可以分为4个阶段,包括预处理(Preprocessing)、编译(Compiling)、汇编(Assembling)和连接(Linking)。 ●预处理程序读取C语言源文件,对其中以“#”开头的指令(伪指令)和特殊符号进行处理。 ●编译程序对预处理之后的输出文件进行词法分析和语法分析,试图找出所有不符合语法规则的部分,并根据问题的大小做出不同处理。在确定各成分都符合语法规则后,将其“翻译”为功能等价的中间代码表示或者汇编代码。 ●汇编程序把汇编语言代码翻译成目标机器代码。 ●连接程序要解决外部符号访问地址问题,也就是将一个文件中引用的符号(如变量或函数调用)与该符号在另外一个文件中的定义连接起来,从而使有关的目标文件连成一个整体,最终成为可被操作系统执行的可执行文件。 6.2 对C语言程序进行编译时,针对以下情况应使用的编译命令行是什么? (1)只生成目标文件,不进行连接。 (2)在预处理后的输出中保留源文件中的注释。 (3)将输出写到file指定的文件中。 (4)指示编译程序在目标代码中加入供调试程序gdb使用的附加信息。 (5)连接时搜索由library命名的库。 答:(1) 只生成目标文件,不进行连接:gcc -c 源文件名 (2) 在预处理后的输出中保留源文件中的注释: gcc -C 源文件名 (3) 将输出写到file指定的文件中: gcc -o file (4) 指示编译程序在目标代码中加入供调试程序gdb使用的附加信息: gcc -g 源文件名 (5) 连接时搜索由library命名的库:gcc -llibrary 6.3 通常,程序中的错误按性质分为哪三种? 答:程序中的错误按其性质可分为以下三种:(1) 编译错误,即语法错误。(2) 运行错误。(3) 逻辑错误。 6.4 gdb主要帮助用户在调试程序时完成哪些工作? 答:gdb主要帮助用户在调试程序时完成四方面的工作: (1) 启动程序,可以按用户要求影响程序的运行行为。 (2) 使运行程序在指定条件处停止。 (3) 当程序停止时,检查它出现了什么问题。 (4) 动态改变程序的执行环境,这样就可以纠正一个错误的影响,然后再纠正其他错误。 6.5 调试下面的程序: /badprog.c错误地访问内存/ #include #include

int main(int argc, char **argv) { char *p; int i; p=malloc(30); strcpy(p,“not 30 bytes”); printf(“p=\n”,p); if(argc==2){ if(strcmp(argv[1], “-b”)==0) p[50]=‘a’; else if(strcmp(argv[1], "-f ")==0){ free§; p[0]=‘b’; } } /free§;/ return 0; } 答:这是上机操作题。先利用gcc -g badprog.c -o badprog对源文件进行编辑;通过编辑后,运行badprog文件,看看出现什么问题;然后利用gdb工具调试该程序。参考书中6.2.6节的示例,依据调试时实际显示的即时信息,分析可能的原因(注意数组大小!),使用相应的命令一步步调试,直至找出问题根源;然后予以改正,再重新编辑、运行。 6.6 调试下面的程序: /callstk.c有3个函数调用深度的调用链/ #include #include

int make_key(void); int get_key_num(void); int number(void); int main(void) { int ret=make_key(); printf(“make_key returns %d\n”,ret); exit(EXIT_SUCCESS); }

int make_key(void) { int ret=get_key_num(); return ret; } int get_key_num(void) { int ret=number(); return ret; } int number(void) { return 10; } 答:这是上机操作题。体会函数调用的层次关系。 6.7 GNU make的工作过程是怎样的? 答:GNU make的工作过程是: ① 依次读入各makefile文件; ② 初始化文件中的变量; ③ 推导隐式规则,并分析所有规则; ④ 为所有的目标文件创建依赖关系链; ⑤ 根据依赖关系和时间数据,确定哪些目标文件要重新生成; ⑥ 执行相应的生成命令。 6.8 makefile的作用是什么?其书写规则是怎样的? 答: makefile文件是make命令必备的一个文本形式的数据库文件,它定义了一系列规则,记录了文件之间的依赖关系及在此依赖关系基础上所应执行的命令序列,即定义了一系列规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译等。此外,还可以有变量定义、注释等。 makefile的通用形式如下所示: 目标文件:[相依文件…] 命令1[#注释] … 命令n[#注释] 其书写规则是:依赖行从一行的开头开始书写。各命令行单独占一行,每个命令行的第一个字符必须是制表符,而不能使用8个空格;#号后的内容为注释。它可以位于一行的开头;在依赖行上,目标文件和相依文件之间要用一个或两个冒号分开。一个目标文件可以出现在多个依赖行上,此时所有的依赖行的类型必须一致(一个冒号或两个冒号)。 6.9 设某个正在开发的程序由以下内容组成: ① 4个C语言源文件:a.c,b.c,c.c和d.c。设b.c和d.c都使用了defs.h中的声明。 ② 汇编语言源文件assmb.s被某个C语言源文件调用。 ③ 使用了在/home/user/lib/libm.so中的一组例程。 设最后生成的可执行文件名为prog。试编写相应的makefile文件。 答:先根据题意,画出依赖关系图,再编写makefile文件。makefile文件如下所示: prog:a.o b.o c.o d.o assmb.o gcc a.o b.o c.o d.o assmb.o -L/home/user/lib -lm –o prog a.o:a.c gcc –c a.c b.o:b.c defs.h gcc -c b.c c.o:c.c gcc -c c.c d.o:d.c defs.h gcc -c d.c assmb.o:assmb.s as -o assmb.o assmb.s clean: rm prog *.o



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3