【转】《APUE》第三章笔记(4)及习题3-2

原文网址:http://www.cnblogs.com/fusae-blog/p/4256794.html

APUE第三章的最后面给出的函数,现在还用不着,所以,先留个名字,待到时候用着了再补上好了。

dup和dup2函数:用来复制文件描述符的

sync函数,fsync函数和fdatasync函数:大致的功能是将缓冲区的数据刷进队列中,等待写入到硬盘中。

fcnti函数:可以改变已打开文件的性质。

ioctl函数:控制设备。

习题:

1.当读/写磁盘文件时,本章中描述的函数是否有缓冲机制?请说明原因。

答:是没有的。上述提到的函数是open,read,write等基于POSIX的函数,是直接调用内核中的一个系统调用。而ISO C的标准输入输出函数才是有缓冲的函数,引入了流的概念。具体可参照这篇文章:http://blog.csdn.net/zhangxinrun/article/details/5873047

2.编写一个与3.12节中dup2功能相同的函数,要求不调用fcntl函数,并且要有正确的出错处理。

答:首先要知道dup2函数的功能和fcntl函数的功能。

dup2函数:

功能:复制一个文件描述符,并返回一个任意指定的文件描述符。

#include <unistd.h>

int dup2(int oldfd, int newfd);

返回:newfd

如果newfd已经打开,则先将其关闭。

fcntl函数:

目前只需知道dup2(oldfd, newfd) 等效于

close(newfd);

fcntl(oldfd, F_DUPFD, oldfd);

思路:

1.先关闭newfd,以防万一。然后利用dup(oldfd),不断产生新的fd,直至fd==newfd,再关闭掉其余的fd。

2.因为oldfd和newfd都代表同一个文件,所以其实就是其文件指针指向同一个文件表。所以给文件指针赋值也行,但是不知道结构体的内容,所以也就无法执行了。

思路1代码:

  1. /*实现dup2函数,不能用fcntl函数*/
  2. #include <unistd.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #define BUFFSIZE    4096
  7. #define SIZE    20
  8. int my_dup2(int oldfd, int newfd);
  9. int main(void)
  10. {
  11. char    *filename = "test";
  12. int newfd = 10;
  13. char    buf[BUFFSIZE];
  14. int oldfd = open(filename, O_RDONLY);   /* 打开一个文件 */
  15. int n;
  16. my_dup2(oldfd, newfd);
  17. /* 将test文件(注意:fd是用了newfd)的内容输出到stdout里 */
  18. while ((n = read(newfd, buf, BUFFSIZE)) > 0)
  19. if (write(STDOUT_FILENO ,buf, n) != n)
  20. {
  21. perror("write error");
  22. exit(1);
  23. }
  24. if (n < 0)
  25. {
  26. perror("read error");
  27. exit(1);
  28. }
  29. close(newfd);
  30. exit(0);
  31. }
  32. int my_dup2(int oldfd, int newfd)
  33. {
  34. int tmp[SIZE];
  35. int i = 0;
  36. if (oldfd == newfd)
  37. return newfd;
  38. close(newfd);
  39. /*利用dup函数不断产生新的fd,如果fd跟newfd相等,则停止*/
  40. while (1)
  41. {
  42. tmp[i] = dup(oldfd);
  43. if(tmp[i] == newfd)
  44. break;
  45. i++;
  46. }
  47. /* 关掉多余的fd */
  48. i = 0;
  49. while (1)
  50. {
  51. if(tmp[i] != newfd)
  52. {
  53. close(tmp[i]);
  54. i++;
  55. }
  56. else
  57. break;
  58. }
  59. return newfd;
  60. }

结果运行如下:

如果将中间那个my_dup2函数注释掉的话,结果如下:

到此,习题3-2解决!

习题部分就做到这里好了,或许有空会更新接下来的习题部分。

时间: 2025-01-02 09:08:22

【转】《APUE》第三章笔记(4)及习题3-2的相关文章

HBase in Action前三章笔记

近期接触HBase,看了HBase In Action的英文版.開始认为还行,做了些笔记.可是兴许看下去,越来越感觉到实战这本书比較偏使用上的细节,对于HBase的具体设计涉及得很少.把前三章的一些笔记帖一下.后面几章内容不打算整理了.并非说书内容不好. key-value存储.强一致性,多个RegionServer节点对client端是不暴露细节的 使用场景:典型的web-search, capture incremental data, ad. click stream, content s

《计算机网络(第7版)谢希仁 著》第三章 数据链路层 要点及习题总结

1.数据链路层的三个基本问题:封装成帧,透明传输,差错检测 2.点对点信道的数据链路层 (1)链路和数据链路 链路(物理链路):链路(link)就是从一个结点到相邻结点的一段物理线路(有线或无线〉,而中间没有任何其他的交换结点 数据链路(逻辑链路):为当需要在一条线路上传送数据时,除了必须有一条物理线路外,还必须有一些必要的通信协议来控制这些数据的传输,换而言之,数据链路=链路+通信协议 (2)早期的数据通信协议叫通信规程 (3)数据链路层的协议数据单元-------帧 (4)封装成帧:封装成帧

apue第三章习题的一些拙见(不定时更新)

写在前面:本人通信专业大二,自学apue,时间有限,这个系列都是抽时间写的,目前已经看到15章,现在从头做题,如有错误还请指教. 第一题: write和read这样的函数都属于系统调用,这里具体所指的没有缓冲区是没有用户缓冲区,而不是指没有内核缓冲区,这里以我个人的认识认为,这里write和read将数据拷贝到缓冲区后并不直接写到文件中,而是等一定条件发生后才写进去,但是具体机制还需研究.同时这里也暴露了一个问题,每次进行I/O都需要进行系统调用,这无疑是对系统资源的一种浪费,所以这也为后来的标

分治习题--九章算法培训课第三章笔记

1.Maximum Depth of Binary Tree 这是道简单的分治习题了 分: 左子树最大深度 右子树最大深度 治: 最大深度等于max(左子树,右子树)+1 public class Solution { public int maxDepth(TreeNode root) { if (root == null) { return 0; } int left = maxDepth(root.left); int right = maxDepth(root.right); retur

深入PHP 第三章笔记

类和对象: 类是对象的模版,对象是类的实例,数据的实例化. 一个类可以生成N个对象,但是这些对象是相同类型的不同个体.就像同一个模子生产的不同手机一样,虽然他们是同一个模子出来的,但是都是单独的个体,在对象的生命周期内,PHP会记录每一个对象. 类的属性的作用域: 对于关键字,public,protected,private用作用域来形容他们更形象一些,因为他们可以定义数据是在外部可以访问还是内部可以访问,规定了数据的访问位置. 关于public的数据类型: 因为PHP是弱类型语言:可以动态给对

第三章笔记

选择结构  (一) 学习本章会用到的单词: if:条件,如果,假如 else:否则 break:打断:跳出循环,停止 continue:继续,持续, match:匹配,比赛 gender:性别 random:随机的,任意的 score:得分:分数.成绩 if选择结构 语法:    if(条件){ 代码块     //条件成立后要执行的代码,可以是一条语句,也可以是一组语句 } 程序执行时,先判断条件.当结果为true时,程序先执行大括号里的代码块,在执行if结构(即{}部分)后面的代码.当结果为

《算法图解》第三章笔记与课后练习

软件环境:Python 3.7.0b4 一.基线条件和递归条件 由于递归函数调用自己,因此编写这样的函数时很容易出错,进而导致无限循环.例如: def countdown(i): print(i) countdown(i-1) countdown(5) # 测试数据 当我们编写递归函数时,必须告诉它何时停止递归.所以,每个递归函数都有两部分: 基线条件(base case):函数调用自己. 递归条件(recursice case):函数不再调用自己,从而避免无限循环. def countdown

java第三章笔记

java的基本程序设计结构: 1. 声明一个变量之后,必须用赋值语句对变量进行显示初始化,千万不能使用未被初始化的变量. 2.在java中不区分变量的声明与定义. 3.当参与/运算的两个操作数都是整数时,表示整数除法:否则表示浮点数除法. 4.自增自减运算符的操作数不能是数值,因为这些运算改变了变量的值. 5.&和|运算符应用于布尔值,得到的结果也是布尔值. 6.java语言允许使用+号拼接两个字符串. 7.当一个字符串与一个非字符串的值进行拼接时,后者被转换成字符串. 8.任何一个java对象

《Android深度探索》卷1 第三章笔记 1314王宁

Git是Linux内核代码对于源代码进行管理操作的软件,它的各方面都要优与其它同类的源代码管理软件. 在安装Git后,查看git文档在Linux下可以使用man命令看指令帮助文档;安装Git-doc后安装Git的文本格式和html格式的文档,所有文档都是存在/usr/sharedoc/git-doc目录中的.可以使用下面的指令来以文本形式查看指定的文档:“# git help <sub-command>” 源代码提交与获取,创建版本库:git init .任何人想要修改git源代码托管服务器中