Linux开发环境及其应用 《第14周单元测验》及其解析

1、使用MemoryMap方式访问磁盘文件,不需要事先用open()系统调用打开文件。由于每个进程可以打开的文件总数是有限的,所以这种文件访问方式可以节约进程的文件描述符资源。

×

查看一下系统调用mmap()的参数,有fd。在Linux内核程序中,open()调用非常复杂,代码量比read()/write()要大得多,除了把i节点之类调入内存完成文件逻辑块与磁盘块之间的映射之外,另外一个重要功能就是完成对文件访问权限的判断处理。所以,即使不用read()、write()机制访问文件,而只是mmap()机制访问文件,留用open的这些安全功能也是有意义的,可以简化系统设计。

2、两个独立的可执行程序a和b,程序运行时,两者通过MemoryMap方式同时访问一个磁盘文件同一位置的数据。这样,不需要通过IPC“共享内存”机制中的semget()和semat()等系统调用也可以实现两独立进程通过共享内存通信,而且,进程无论正常或者异常终止,都可以做到将修改过的数据自动持久化存储到磁盘文件中。

有的同学的程序存在这样的问题,打开文件后访问文件,不执行close()程序就直接退出。回想一下我们之前介绍的三级的“活动文件目录”,程序退出时,操作系统可以知道进程打开过哪些文件,自动关闭它。如果你的程序是长期运行,访问过的文件不关闭,再打开新的文件,会导致文件描述符资源耗尽,就如同僵尸进程占尽进程槽而无法创建新进程一样,新文件无法打开。正常情况,文件访问完毕,执行munmap()调用,再执行close(),但进程异常终止,通过进程页表找到相关页面,可以完成munmap()的功能,文件也一样会被自动close(),执行文件关闭的操作。

3、使用cat打印出一个有100行数据的文本文件,但只能显示出前50行,后50行被阻塞而迟迟不能显示。出现这种现象的一种可能原因是:其他某进程使用fcntl()系统调用将这个文件的后50行数据上了“写锁”,因为写锁锁定时不允许读导致cat被阻塞,如果该进程上锁类型是“读锁”,那么,cat只是打开文件读,将不会被阻塞。

×

这个题我也做错了,读题容易被题目带到沟里
fcntl执行的是“咨询式锁定”不是“强制性锁定”,cat读文件时直接read()并不做fcntl(),不做fcntl()就不会导致cat进程阻塞在“写锁”上

4、某程序仅使用read()/close()系统调用访问文件,程序主流程为

     fd = atoi(argv[1]);
      while ((n = read(fd, buf, sizeof buf)) > 0) { 
              ... 
      }
      close(fd);

程序被exec()系统调用加载前,以命令行参数方式传递一个已经事先打开好的文件描述符。这样,无论fd引用的是磁盘文件,匿名管道,命名管道,终端设备文件,socket,程序均能正常工作。

这正是“一切皆文件”的设计思路带来的好处。你若能开发一个特定虚拟设备, 通过fd = open("/dev/myMicroPhone", O_RDONLY);打开读,你能把麦克风的语音输入变成文本,那么,上面的处理程序也不需要做任何改动。完美!

5、Linux设计得非常健壮,一直以运行稳定而著称。当系统中多个进程因为对信号量操作出现不恰当的P操作和V操作将导致死锁时,semop()系统调用将直接返回-1,系统拒绝错误的操作,从而避免死锁的发生。

×

策略与机制相分离

6、对信号量的P操作有可能导致进程进入阻塞状态,也有可能不进入阻塞状态,但是V操作确定不会导致当前进程进入阻塞状态。

V操作要让当前进程进入阻塞状态,阻塞起来有什么意义?等什么事件?都不需要。所以,V操作不会导致当前进程阻塞,但可以想象,在内核代码里,会导致相关联P操作的进程从“阻塞态”中解除。

7、UDP提供了不可靠数据报服务,但如果通信线路没有任何误码和数据丢失,接收进程可以接收到发送进程发来的所有数据。

×

UDP没有“流量控制机制”,所以,即使通信线路没有任何差错,也有可能接收缓冲区满导致不得不丢弃数据,接收进程无法获得发送方发出的这个数据

8、UDP提供了不可靠服务,所以通信线路误码导致的数据比特被翻转会传递到UDP之上的应用层程序,因此对于一些重要的应用使用UDP通信应增加类似CRC等校验机制。

×

链路层的校验已经很强了,有线以太网和WiFi都提供了CRC32校验,历数所有链路层协议,只有已被淘汰的SLIP协议没有校验,其他全部有校验。这个是协议体系结构中的安排,把强校验放到链路层,因为链路层一般是硬件实现的,硬件做校验比CPU软件实现开销要小,就算软件实现的PPP over serial line,也有软件查表法计算CRC。所以,链路层可以发现(算然不见得有自动重传来纠正误码)误码。退一步讲,UDP自己也有校验和。UDP校验和是选项,校验和域0,就是没有校验;校验和非零,就采用了算术和校验(这个CPU擅长,但CPU不擅长CRC),若凑巧算术和校验是0,就在校验域填写-1。你可以WireShark看一下,你的UDP都有校验和吗?

9、TCP向应用程序提供了“可靠的面向连接的字节流”服务,因此,应用程序交付给TCP的数据总能准确地传送到接收方,网络丢包会导致自动超时重传,网络导致的数据乱序也被纠正。

×

这道题容易把人往沟里带,首先明确的是,TCP可靠的面向连接的字节流,数据总能准确的传送给接收方。但是要记住的是,面向连接,发送的字节流就一定保证了有序,前面发送的字节流没有获得ack确认,那么就不会在传下一个包,即便使用了滑动窗口协议或者选择重传(允许前一个数据未确认就发下一数据),发送的数据也同样是保持有序传输的。TCP会导致网络丢包,但是不会导致数据乱序。

你可能感兴趣的:(Linux)