【断更一段时间】CSAPP笔记07系统级IO

【断更一段时间】CSAPP笔记07系统级IO

​ 在开始本章之前,我的秋招刚刚开始,也刚刚结束,百度移动客户端二面凉了。其实我投了蛮多互联网企业的,但是经过百度的面试,我发觉在操作系统和计算机网络方面我还是太浅了,要掌握的还有很多,另外,我对这两门课程缺少实践,理解肤浅,这种实践可能对于应届生面试而言不是必须的,但是作为程序员,作为工程师,没有经历正式项目的洗礼,总是青涩稚嫩的。所以我打算直接不参加后面的秋招了,再次闭关,等神功大成了,再去春招。我知道春招的HC少。但是热爱coding的人,对技术都有着无与伦比的狂热,对自己有着盲目的自信。这种狂热和自信,是枯燥平凡生活里为数不多的亮色。

​ 再回到CSAPP这本书,这本书是计算机组成原理和操作系统概述的串讲。这本书的优点在于,它使用了很多的图片,行文简练没有废话,结构合理,在适当的地方有合适的检测题目,对于初学者来说很容易跟着其入门。但是它只能算是一本入门书,对于操作系统里的进程管理、内存管理和文件系统都只是介绍了最基本的原理,对于现在主流的系统的这三种功能的细节和实现,并没有提到,这也不是这本书的功能。

​ 我原先想的是,读完这本书,在这阅读这本书的时候自己扩展学习,来完成操作系统和计算机网络的学习。但是实际上这还是不够的。充分弄懂这本书,然后还需要专门对操作系统和计算机网络进行学习。最后我还需要做一些合适的项目,从项目中夯实基础,加深对理论的理解。我觉得实现一个webserver或者kernel的雏形大概是个不错的项目。毕竟我买了一本《操作系统真象还原》。

​ 关于编程语言,c语言是一门很古老的语言了,当然它在今天,某些工程领域还在使用。但是在互联网企业,c语言很少被使用,因为他不够“快”,开发的速度太慢了。一方面,他缺少很多语法糖,缺少很多编程范式;另一方面,他对内存的操作又要十分谨慎。所以开发、维护一个大型的c语言的项目是不明智。

​ 但是选择一门编程语言对现在的我来说是一件纠结的事,因为我没有进行实际的项目,没有动力去进行编程语言技能的更新,说白了,c语言对处在学习阶段的我来说,简洁够用!但是另一方面,我也知道要进入互联网企业,必须的选一门现代的,工程便捷的,主流的开发语言。可是C++看起来规范很乱,不够优雅,JAVA看起来不够极客,又臃肿,其余的语言又不够主流。我郁闷,选一门除c以外的编程语言来学习,简直是让我从一堆shit中,选一坨吃,不过如果非吃不可的话,那我大概会选C++了。我考虑在实现webserver的时候学习C++

0x00 概述

​ IO即input output,外部设备输入到主存,主存输出到外部设备。这里的外部设备包括:磁盘驱动器、网卡以及终端(显示设备)。

​ 所有的语言,都提供较高几倍的IO操作,比如ANSI C提供标准IO库,包括printf,scanf,这样执行带缓冲的I/O函数。所谓带缓冲与不带缓冲,指的是函数内部没有中间缓冲区,因为所有I/O最终调用了系统调用read/write,这两个调用将数据从用户缓冲区(输入的指针)复制到内核缓冲区。也就是内核是对I/O有缓冲的,不能保证立即对物理设备读写。典型的就是无缓冲函数write写数据到文件,但是不调用fflush,打开文件发现没变。

​ 大多数时候,我们使用C语言的标准的高级别的I/O即可。但是也有需要使用UNIX I/O的时候。

0x01 UNIX I/O

​ 在linux中,所有I/O设备都是(网络、终端和磁盘)都被模型化为文件,而文件是字节数组。所有的输入输出都被当作文件的读和写来执行,因此所有的输入输出都能以一种一致的方式来执行:

​ 1、打开文件,进程通过调用系统调用来要求内核打开相应的文件,来访问一个I/O设备。内核返回一个小的非负整数,叫做描述符(file descriptor),该描述符标记进程中打开的不同的文件(I/O)设备。内核中记录这个打开文件的所有信息,进程中只需记录这个描述符即可。

​ 2、linux shell创建的每个进程开始时都有三个打开的文件:标准输入(fd为0),标准输出(fd为1)和标准错误(fd为2)。头文件< unistd.h >中定义了常量STDIN_FILENO STDOUT_FILENO和STDERR_FILENO宏常量。

​ 3、改变当前的文件位置、对于每个打开的文件,内核保存着一个文件位置(但是一个文件可以被打开多次,拥有不同的文件位置),初始为0。这个文件位置是从文件开头的偏移。(某些类型的文件)可以用过lseek系统调用显示的设置文件位置。

​ 4、读写文件、一个读操作是从文件当前位置k开始复制N个字节到内存(一般是先复制到内核缓冲区,内核再复制给进程),让后将k增加到k+N。同样的写操作是从内存复制(显示进程的用户态复制到内核里)N个字节到文件当前位置k处,然后更新k。

​ 5、关闭文件、当进程完成对文件的访问后,就通知内核关闭这个文件。内核创建打开文件时创建的数据结构,并将描述符恢复到可以的描述符池。并且,无论进程因何原因终止,内核都会关闭所有它打开的文件,并释放内存资源。

0x02 文件

​ 每个linux文件对应下面的类型之一,表明其在系统内的角色:

普通文件:包含任意数据,用户进程可能需要区分二进制文件和普通文本文件,但是对于系统来说,都是普通文件

目录:是一组包含链接(link)的文件,每个链接都将一个文件名(file name)映射到一个文件。当然这个文件的类型也可能是另一个目录。每个目录都至少有两个条目,一个是 . 一个是..前者对应当前目录,后者对应上一级目录。

套接字(socket):套接字是用来远程通信的文件。

​ 其他的文件类型还包括 :命名管道(named pipe) 符号链接(symbolic link) 以及设备(device)

image-20200822153654966

​ linux将所有文件组织成目录层次结构

//写到这里突然弃更了,不为什么,写了好多,突然觉得没意思了,毕竟这本书的后面三章我都提前看完了,没有之前一章一章阅读的新鲜感了,现在没心情更新了,以后会不会更新? 我可能会更新后面的远程shell的lab吧。

//后面的时间,准备转到《操作系统真象还原》这本书了,但是不会写博客了,准备动手开始写内核,经历这一次面试之后,真切的感受到,靠背记概念,永远不能真切的掌握操作系统和计算机网络这两门课程,绝知此事要躬行