习题

1.一个目录包含以下的文件:

阅读 ‧ 电子书库

哪些文件能通过命令ls[abc]*e*被罗列出来?

2.下面的Linux shell管线的功能是什么?

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元


grep nd xyz|wc-|


3.写一个能够在标准输出上打印文件z的第八行的Linux管线。

4.Linux在标准输出和标准错误对于终端都是默认的情况下是怎么区分标准输出和标准错误的?

5.一个用户在终端键入了如下的命令:


a|b|c&

d|e|f&


在shell处理完这些命令后,有多少新的进程在运行?

6.当Linux shell启动一个进程,它把它的环境变量,如HOME放到进程栈中,使得进程可以找到它的home目录是哪个。如果这个进程之后进行派生,那么它的子进程也能自动地得到这些变量吗?

7.在如下的条件下:文本大小=100KB,数据大小=20KB,栈大小=10KB,任务结构=1KB,用户结构=5KB,一个传统的UINX系统要花多长时间派生一个子进程?内核陷阱和返回的时间用1ms,机器每50ns就可以复制一个32位的字。共享文本段,但是不共享数据段和堆栈段。

8.当多兆字节程序变得越来越普遍,花在执行fork系统调用以及复制调用进程的数据段和堆栈段的时间也成比例地增长。当在Linux中执行fork,父进程的地址空间是没有被复制的,不像传统的fork语义那样。Linux是怎样防止子进程做一些会彻底改变fork语义的行动的?

9.当一个进程进入僵死状态后,取走它的内存有意义吗?为什么?

10.你认为为什么Linux的设计者禁止一个进程向不属于它的进程组的另一个进程发信号呢?

11.一个系统调用常用一个软件中断(陷阱)指令实现。一个普通的过程调用在Pentium的硬件上也能使用吗?如果能使用,在哪种条件下?如何使用?如果不能,请说明原因。

12.通常情况下,你认为守护进程比交互进程具有更高的优先级还是更低的优先级?为什么?

13.当一个新进程被创建,它一定会被分配一个惟一的整型数作为它的PID。在内核里有一个每个进程创建时就递增的计数器够用么?其中计数器作为新的PID。讨论你的结论。

14.在每个任务结构中的进程项中,父进程的PID被储存。为什么?

15.当响应一个传统的UNIX fork调用时,Linux的clone命令会使用什么样的sharing_flags位的组合?

16.Linux调度器在2.4版本和2.6版本的内核间经历了一个大整修。现在的调度器可以在O(1)时间做出调度决定。请解释为什么会这样?

17.当引导Linux(或者大多数其他操作系统在引导时)时,在0号扇区的引导加载程序首先加载一个引导程序,这个程序之后会加载操作系统。这多余的一步为什么是必不可少的?0号扇区的引导加载程序直接加载操作系统会更简单的。

18.某个编辑器有100KB的程序文本,30KB的初始化数据和50KB的BSS。初始堆栈是10KB。假设这个编辑器的三个复制是同时开始的。(a)如果使用共享文本,需要多少物理内存呢?(b)如果不使用共享文本又需多少物理内存呢?

19.在Linux中打开文件描述符表为什么是必要的呢?

20.在Linux中,数据段和堆栈段被分页并交换到一个特别的分页磁盘或分区的暂时副本上,但是代码段却使用了可执行二进制文件。为什么?

21.描述一种使用mmap和信号量来构造一个进程内部间通信机制的方法。

22.一个文件使用如下的mmap系统调用映射:


mmap(65536,32768,READ,FLAGS,fd,0)


每页有8KB。当在内存地址72000处读一个字节时,访问的是文件中的哪个字节?

23.在前一个问题的系统调用执行后,执行munmap(65535,8192)调用会成功吗?如果成功,文件的哪些字节会保持映射?如果不成功,为什么会失败?

24.一个页面故障会导致错误进程终止吗?如果会,举一个例子。如果不会,请解释原因。

25.在内存管理的伙伴系统中,两个相邻的同样大小的空闲内存块有没有可能同时存在而不会被合并到一个块中?如果有解释是怎么样的情况。如果没有可能,说明为什么不可能。

26.据说在代码段中分页分区要比分页文件性能更好。为什么呢?

27.举两个例子说明相对路径名比绝对路径名有优势。

28.以下的加锁调用是由一个进程集合产生的,对于每个调用,说明会发生什么事情。如果一个进程没能够得到锁,它就被阻塞。

a)A想要0到10字节处的一把共享锁。

b)B想要20到30字节处的一把互斥锁。

c)C想要8到40字节处的一把共享锁。

d)A想要25到35字节处的一把共享锁。

e)B想要8字节处的一把互斥锁。

29.考虑图10-26c中的加锁文件。假设一个进程尝试对10和11字节加锁然后阻塞。那么,在C释放它的锁前,还有另一个进程尝试对10和11字节加锁然后阻塞。在这种情况下语义方面会产生什么问题?提出两种解决方法并证明。

30.假设lseek系统调用在一个文件中寻找一个负的偏移量。给出两种可能的处理方法。

31.如果一个Linux文件拥有保护模式755(八进制),文件所有者、所有者所在组以及其他每个用户都能对这个文件做什么?

32.一些磁带驱动拥有编号的块,能够在原地重写一个特定块同时不会影响它之前和之后的块。这样一个设备能持有一个已加载的Linux文件系统吗?

33.在图10-24中链接之后Fred和Lisa在他们各自的目录中都能够访问文件x。这个访问是完全对称的吗,也就是说其中一个人能对文件做的事情另一个人也可以做?

34.正如我们看到的,绝对路径名从根目录开始查找,而相对路径名从工作目录开始查找。提供一种有效的方法实现这两种查找。

35.当文件/usr/ast/work/f被打开,读i节点和目录块时需要一些磁盘访问。在根节点的i节点始终在内存中以及所有的目录都是一个块的大小这样的假设下计算需要的磁盘访问数量。

36.一个Linux i节点有12个磁盘地址放数据块,还有一级、二级和三级间接块。如果每一个块能放256个磁盘地址,假设一个磁盘块的大小是1KB,能处理的最大文件的大小是多少?

37.在打开文件的过程中,i节点从磁盘中被读出,然后放入内存中的i节点表里。这个表中有些域在磁盘中没有。其中一个是计数器,用来记录i节点已经被打开的次数。为什么需要这个域?

38.在多CPU平台上,Linux为每个CPU维护一个runqueue。这是个好想法吗?请解释你的答案。

39.pdflush线程可以被周期性地唤醒,把多于30秒的旧页面写回到磁盘。这个为什么是必要的?

40.在系统崩溃并重启后,通常一个恢复程序将运行。假设这个程序发现一个磁盘i节点的连接数是2,但是只有一个目录项引用了这个i节点。它能够解决这个问题吗?如果能,该怎么做?

41.猜一下哪个Linux系统调用是最快的?

42.对一个从来没有被连接的文件取消连接可能吗?会发生什么?

43.基于本章提供的信息,如果一个Linux ext2文件系统放在一个1.44MB的软盘上,用户文件数据最大能有多少可以储存在这个盘上?假设磁盘块的大小是1KB。

44.考虑到如果学生成为超级用户会造成的所有麻烦,为什么这个概念还会出现?

45.一个教授通过把文件放在计算机科学学院的Linux系统中的一个公共可访问的目录下来与他的学生共享文件。一天他意识到前一天放在那的一个文件变成全局可写的了。他改变了权限并验证了这个文件与他的原件是一样的。第二天他发现文件已经被修改了。这种情况为什么会发生,又如何能预防呢?

46.Linux支持一个系统调用fsuid。setuid准许使用者拥有与他运行的程序相关的有效id的所有权利。与setuid不同,fsuid准许正在运行程序的使用者拥有特殊的权利,只能够访问文件。这个特性为什么有用?

47.写一个允许简单命令执行的最小的shell,也要使这些命令能在后台执行。

48.使用汇编语言和BIOS调用,写一个在Pentinum类计算机上从软盘上引导自己的程序。这个程序应该使用BIOS调用来读取键盘以及回应键入的字符,只是证明这个程序确实在运行。

49.写一个能通过串口连接两台Linux计算机的哑(dumb)中断程序。使用POSIX终端管理调用来配置端口。

50.写一个客户-服务器应用程序,应答请求时能通过套接字传输一个大文件。使用共享内存的方法重新实现相同的应用程序。你觉得哪个版本性能更好?为什么?使用你写好的代码和不同的文件大小进行性能的测量。你观察到了什么?你认为在Linux内核中发生了什么导致这样的行为?

51.实现一个基本的用户级线程库,该线程在Linux的上层运行。库的API应该包含函数调用,如mythreads_init、mythreads_create、mythreads_join、mythreads_exit、mythreads_yield、mythreads_self,可能还有一些其他的。进一步实现这些同步变量,以便用户能使用安全的并发操作:mythreads_mutex_init,mythreads_mutex_lock,mythreads_mutex_unlock。在开始前,清晰地定义API并说明每个调用的语义。接着使用简单的轮转抢占调度器实现用户级的库。还需要利用该库编写一个或更多的多线程应用程序,用来测试线程库。最后,用另一个像本章描述的Linux2.6 O(1)的调度策略替换简单的调度策略。使用每种调度器时比较你的应用程序的性能。