久闻apue这本大名鼎鼎的书,趁着上os课,暗下决心好好从头开始读。
本笔记不会写得太过详细,只会写清楚UNIX大体框架,每一部分都需要读者另外找资料学习,但作为总结是个不错的选择。
文件和目录
目录的起点为root,其名字是字符/。
当创建了一个新目录时,自动创建了两个文件名:“.”和“..”。“.”引用当前目录,“..”引用父目录。在系统调用”cd”里面常用这两个命令。
每个进程都有一个工作目录(working directory),所有相对路径名都是从工作目录开始解释。进程可以用chdir函数来改变其工作目录。
输入和输出
文件描述符是一个小的非负整数,内核用以标识一个特定进程正在访问的文件。当内核打开一个现存的文件或者创建一个新文件时,它就返回一个文件描述符。
每当运行一个新程序时,所有的shell都会为其打开三个文件描述符:标准输入,标准输出,标注出错。其中,标准输入对应STDIN_FILENO,标准输出对应STDOUT_FILENO,典型值为0,1。
程序和进程
程序是放在磁盘文件中的可执行文件,使用6个exec函数中的一个由内核将程序读入存储器,并执行。
程序的执行实例称为进程(process),进程有(PID)作为数字标识符。
fork,exec,waitpid是主要用于进程控制的函数。使用getpid可以得到当前进程的PID。
原始系统数据类型
pid_t,size_t,等以t结尾的这些数据类型被称为原始系统数据类型,它们通常在头文件< sys/types.h >中定义(头文件< unistd.h >已经包含该头文件)。
它们的目的是阻止程序使用专门的数据类型(例如int,short,long)来允许一种特定系统的每个实现选择所需要的数据类型。
出错处理
当UNIX函数出错时,往往返回一个负值,而且整型变量errno通常设置为具有特定信息的一个值。而返回一个指向对象的指针的大多数函数,在出错时将返回一个null指针。
< errno.h >定义了变量errno。有两条规则需要牢记:
- 如果没有出错,则其值不会被一个例程清除,因此,当且仅当函数的返回值指明出错时,才检验其值。
- 任一函数都不会讲errno值设置为0.
UNIX时间值
UNIX使用日历时间和进程时间。
度量一个进程的执行时间有三种时间值:
时钟时间
又称为墙上时钟时间(wall clock time),它是进程运行的时间总量,其值与系统中同时运行的进程数有关。
用户CPU时间
指执行用户指令所用的时间量。
系统CPU时间
指为进程执行内核所经历的时间。例如read或write的时间。
使用以下命令可清晰看出这三者的区别:
time ps -ef | grep 1
系统调用和库函数
UNIX为每个系统调用在标准C库函数中设置一个具有相同名字的函数。用户进程用标准C调用序列来调用这些函数,然后,函数又用系统所要求的技术调用相应的内核服务,例如函数可将一个或多个C参数送进通用寄存器,然后执行某个产生软中断进入内核的机器指令。
值得注意的是,这些通用函数可能调用一个或者多个内核的系统调用,但并不是内核的入口点。例如,strcpy或atoi并不会使用任何系统调用。
系统调用和库函数有很大差别,例如我们可以调用malloc动态分类内存,而在UNIX系统调用中处理存储器分配的是sbrk,它增加或者减少指定字节数的进程地址空间。但如何管理该地址空间却取决于进程。我们知道,有很多种方法可以进行存储器分配(first-fit,bes-fit等),这些算法都由进程决定。
欢迎关注我的个人博客。