基本看完了《unix/linux编程实践教程》,实现了几个小项目,觉得很不过瘾,书中对很多system call的细节和原理都没讲。在尝试看linux内核分析的书时发现很多困难,所以拿起apue,继续打基础。读着读着,对apue上瘾了。这是题外话,就说这么多。
相关阅读:
Unix/Linux编程实践教程【高清PDF中文版+附录光盘+代码】:
一.我对文件I/O的理解
文件I/O最基本的两个函数就是read和write,书中也叫做unbuffered I/O。刚看到这个"unbuffered",我就奇怪,操作系统不是对所有的输入输出都会做缓存吗(delayed write),为什么还会存在unbuffered?但接着我就明白了,这里的ubuffered,是指的是针对与read和write本身来说,他们是没有缓存机制,比如read(fd,temp,100),在读够100个字节后或者遇到文件EOF后就返回,非常单纯。而C库函数中的fread和fwrite,就是利用缓存技术来调用read和write,可以说是buffered I/O。
二.文件描述符
文件描述符是一个整型,可以理解为一个指向文件的指针(注:整型也可以理解为一个指针,并不是只有void*才可以被叫做指针)。需要注意的就是,一个进程在结束的时候会关闭所有打开的文件描述符,但是0,1,2除外。0,1,2,分别代表标准输入流,标准输出流和标准错误流。这3个文件描述符是由kernel打开和进行管理的,不需要我们来打开和关闭。
三.文件共享机制
比较重要的就是file table的理解。file table包括了file status flags,the current file offset,a pointer to the v-node table entry for the file.比如对文件temp,调用一次open后,有fd1指向temp,也就有了一个file table。再对temp调用一次open后,有fd2指向temp,再生成一个file table(可以用dup,dup2实现,但又有不同,见下文)。这时,排除其他因素,我们的系统中有一个temp文件,2个文件描述符:fd1,fd2,两个file table(表示同一个文件)。需要注意的是,如果对write操作加上了排他锁,就无法用O_WRONLY同时打开两个文件描述符了。但可以用O_RDONLY同时打开两个文件描述符,fd1,fd2可以同时读,而相应的,fd1指向的file table的current file offset自然可以不同于fd2指向的,这也就可以很容易地理解多个file table的作用了。
四.system call原理与分析
我喜欢用函数来总结所学的东西,感觉比较实在。
1.lseek(fd,5,SEEK_SET).修改current offset.返回新的offset.
2.open(file,O_RDWR).不赘述细节,详见man。先写一个问题,就是O_SYNC,我无法利用代码来感受这个option,如果您能帮忙,小弟我非常感激。值得注意的就是O_APPEND,这个很强大的东西,跟>>重定向的"添加到末尾"是一样的。特别注意,当open(file,O_RDWR | O_APPEND)后,write与read得到的待遇并不相同。每个被打开的文件都有一个current offset,可以用lseek对这个offset进行修改。先贴出代码:
int main()
{
int fd;
char buf[100]="abcde";
//注:temp中只有一行aaaaabbbbbccccc.
if( (fd=open("temp",O_RDWR|O_APPEND))<0 )
err_sys("error open!");
if(lseek(fd,5,SEEK_SET)==-1)
err_sys("error lseek!");
if( read(fd,buf,5)<0 )
err_sys("error read!");
buf[5]='\0';
printf("%s\n",buf);
//if(write(fd,buf,5)!=5)
// err_sys("write error");
return 0;
}