admin 管理员组文章数量: 1086019
2024年3月13日发(作者:termux工作目录)
UNX环境高级编程第三章课后习题解析
3.1
当读
/
写磁盘文件时,本章中描述的函数是否有缓冲机制?请说明原因。
解析:
write
这两个系统调用。这两个函数由于是系本章中的函数应该是特指
read
、
统调用,因此这两个函数都是在内核中进行,所以称之为不带缓冲的
I/O
函数。
而带有缓冲的函数本质上是依赖一段额外的内存空间作为临时缓冲区,这样做可
以避免一些不当的设置导致读写性能较低的问题,例如标准
I/O
函数中的
gets
等函数大致就是这样的。很显然,系统调用
read
和
write
并没有借助这样的技术。
3.2
编写一个与
3.12
节中
dup2
功能相同的函数,要求不调用
fcntl
函数,并且
要有正确的出错处理。
解析:
既然不能够使用
fcntl
函数,那么我们实现只能考虑使用
dup
函数,当然这个
实现方式相对来说非常的暴力。首先我们关闭指定的新描述符,之后我们开始暴
力的调用
dup
函数,直到
dup
函数返回值与指定的新描述符值相同为止,在这个
过程中我们要通过一个线性的结构来记录中间所有被
dup
调用打开的描述符。这
些描述符的打开并不是我们预期的,随后我们必须逐个关闭这些描述符,否则不
但会额外占用大量的系统资源,导致进程无法打开新的文件,还导致了通过其它
描述符也可以对文件进行访问,所以它们必须被关闭。
至于错误处理问题,我们就需要关心一下
errno
这个东西了,如果仅仅从
errno
入手的话,我们没有必要在一开始就检查这个指定的新描述符值是否小于系统中
的限制值,只需关心它是否为非负数就可以了,在之后的不断调用
dup
函数的过
程中,如果如果
dup
函数出现错误就直接返回
-1
就是了,这里也会包括无法在打
开更多描述符的问题,在忽视其他进程也调用类似函数的情况下这说明我们指定
的新描述符值相对来说太大了。至于
errno
值就不必关心了,这个值仅仅在函数
出现错误的时候可能会用到,而且不会在任何库函数调用前被重置。因此,当我
们自己编写的函数出错返回时,
errno
值会被保留,我们可以大概知道是在哪一
步出现了错误。
这里我们或许可以借助
sysconf
函数来获取系统对一个进程打开最大描述符
的限制,使用
sysconf
函数获取相关限制是一个很好的编程习惯,这使得代码具
有更好的移植性,详细内容请参考《
UNIX
环境高级编程》第
2.5
节。
在最后我们需要补充一点,那就是当原始描述符与新指定的描述符值相同的
情况,如果此时直接将新指定的描述符关闭的话,那么恐怕就要出现问题了,很
显然这和我们的预期并不相符。
3.3
假设一个进程执行下面的
3
个函数调用:
fd1=open(pathname,oflags);
fd2=dup(fd1);
fd3=open(pathname,oflags);
画出类似于图
3-3
的结果图。对
fcntl
作用于
fd1
来说,
F_SETFD
命令会影
响到哪个文件描述符?
F_SETFL
呢?
解析:
这道题的关键之一就是画出结果图,这一点非常重要,只要图画出来了一切
都好解释了。首先
fd2
描述符是由
fd1
描述符直接通过
dup
函数复制而来,那么
我们可以看到这两个描述符其实是共享同一个文件表的。而
fd3
则是通过
open
函数与
fd1
打开了同一个文件,不过这两个描述符是不可能共享一个文件表的,
只不过由于打开的是同一个文件,那么二者的文件表中
v
节点指针的指向是相同
的。了解这些之后结果图很容易就可以画出来了。
接下来我们要明确的是文件表中都有些什么,根据《
UNIX
环境高级编程》
的讲解,文件表中一共有三项:文件状态标志、当前文件变量和
v
节点指针。这
一点至关重要,如果不明确这点就很难得出最终的正确结论。除此之外,了解
fcntl
函数中指定
F_SETFD
和
F_SETFL
的作用也同样重要,
F_SETFD
作用是修改文
件描述符标志的作用,这个是仅仅对当前文件描述符起作用的,所以受影响的描
述符仅有
fd1
。而对于
F_SETFL
而言,是修改这个文件描述符打开文件的状态标
志,这个状态标志指的无非就是
O_RDONLY
之类的(详见
open
函数论述)。我
们发现这个部分居然在文件表中存储,那么我们可以断定与
fd1
共享一个文件表
的文件描述符都将会受到影响,所以此时受影响的文件描述符为
fd1
和
fd2
。
3.4
在许多程序中都包含下面一段代码:
dup2(fd,0);
dup2(fd,1);
dup2(fd,2);
if(fd>2)
close(fd);
为了说明
if
语句的必要向,假设
fd
是
1
,画出每次调用
dup2
时
3
个描述符
项及相应的文件表项的变化情况。然后画出
fd
为
3
的情况。
解析:
到这里相信图不再难画,如果对这个状态图仍然有疑问,那么就需要回头对
3.10
节中的内容好好研究一番了。不过问题是即使是画出图来也看不出什么问
题,感觉一切都很正常。我们很难看出调用
close
的必要性,很明显文件描述符
可以被成功复制的次数与题干中的过程没有直接关联。
这里应该是包含这一个隐含的条件,在复制完文件描述符之后,仅仅希望通
过描述符
0
、
1
和
2
进行对文件的访问。这样一来问题便能解释通了,如果是在
这样一个期望的前提下,调用
close
就有必要性了。不过我们不应该忽视的是文
件描述符
0
到
2
通常对应的分别是标准输入、标准输出和标准错误输出。这样做
一定是有特别用意的,我们不妨在以后的代码中注意一下这个问题。
3.5
在
Bourneshell
、
Bourne-againshell
和
Kornshell
中,
digit1>&digit2
表
示要将描述符
digit1
重定向至描述符
digit2
的同一文件。请说明下面两条命令的
区别。
./>outfile2>&1
./2>&1outfile
(提示:
shell
从左到右处理命令行)
解析:
这个就是按照命令做解释就可以了,很容易就会发现两个命令的含义完全不
版权声明:本文标题:UNX环境高级编程第三章课后习题解析 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1710298015a566712.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论