本章对一些术语进行简要说明并给出实例。
文件和目录
stat和fstat函数返回包含所有文件属性的一个信息结构。第四章将详细说明文件的各种属性。
目录项的逻辑视图与实际上的磁盘存放方式是不同的。UNIX文件系统大多数实现并不在目录项中存放属性,这是权衡于硬连接带来的一些问题。第四章将讨论。
文件名
只有斜线和空字符不能出现在文件名中。斜线用来分割路径名,空字符终止一个路径名。opendir
函数与readdir
函数,包含于dirent.h
中,并且包含对dirent
结构的定义。
opendir函数返回只想DIR结构的指针。将指针传送给readdir函数,使用循环读取每个目录项,返回指向dirent结构的指针,如果没有了则返回null指针。此目录项顺序非首字母排序。
工作目录
working directory,或current working directory。进程可以使用chdir函数更改工作目录。
登陆时cwd设置为起始目录home directory。该目录从口令文件(通常是/etc/passwd)中相应用户的登录项中取得。
输入输出
文件描述符
file descriptor,通常是一个小的非负整数,内核用以标识一个特定进程正在访问的文件。当内核打开一个现有文件或创建一个新文件时,都将返回一个文件描述符。读写文件时可以使用这个文件描述符。
标准输入、标准输出和标准错误
运行一个新程序时shell都将打开3个文件描述符,即以上三者。如果没有特殊处理,则他们都链接向终端。shell可以提供一种方法将它们重新定向到某个文件,例如:
1 | ls > file.list |
这个就是将标准输出重新定向到file.list文件。
不带缓冲IO
open、read、write、lseek和close函数提供了不带缓冲的IO,这些函数都使用文件描述符。
例子:
1 |
|
标准IO
例子:
1 |
|
程序和进程
程序
程序是个文件,内核使用7个exec函数中的一个将其读入内存并执行。
进程和进程ID
程序运行实例被称为进程,不多说了。
UNIX系统确保每个进程都有一个唯一的数字成为process ID,总是一个非负整数。
使用getpid
函数返回一个pid_t
类型数据,按照标准它被存在一个long中。
程序控制
fork、exec(包含7个变体)和waitpid函数是用于进程控制的三个主要函数。
例子:
线程和线程ID
线程是对某个特定进程而言的,因此同一进程内的所有线程共享同一地址空间、文件描述符、栈以及与进程相关的属性。
线程也用ID标识,只是只在所属的进程内起作用。
出错处理
UNIX系统函数出错时通常返回一个负值,而且整型变量errno通常被设置为具有特定信息的值。有的函数例如大多数返回指向对象指针的函数在出错时会返回null指针。errno.h
中定义了errno以及各种常量,这些常量都以E
开头。
每个线程有属于自己的局部errno以避免相互干扰。
注意:
- 没有出错,其值不会被清除,因此进党函数返回出错才检验其值。
- 任何函数不会将errno设置为0,并且errno.h中的所有常量都非0。
例子:
出错恢复
可以将errno.h中的出错分成两类:
- 致命性:无法执行恢复,最多只能输出一条出错,然后quit。
- 非致命性:可以较妥善地处理。
用户标识
用户ID
user ID是一个数值,用于向系统标识各个不同的用户。用户不能更改ID。
0为root。管理员在确定一个用户登陆名的同时,user ID也就确定了。
组ID
group ID也是在指定用户登录名时分配的。
组文件将组名映射为数值的组ID。通常是/etc/group
。
现今UNIX系统使用32位整型表示user ID和group ID。
例子:
附属组ID
信号
signal(信号)用于通知进程。例如除数为0时进程将收到浮点异常SIGFPE
。
三种处理方式:
- 忽略信号:不推荐使用。
- 按系统默认方式处理:除数为0默认处理是终止该进程。
- 提供一个函数,信号发生时调用该函数,这被称为捕捉。
终端键盘有两种产生信号的方法:interrupt key
也就是中断键通常是Delete
或^C
,quit key
也就是退出键通常是^\
,用于中断当前运行的进程。
调用kill函数可以向另一个进程发送一个信号。前提是我们必须是那个进程的所有者或者是超级用户。
例子:
时间值
- 日历时间:从协调世界时(Coordinated Universal Time, UTC)1970年1月1日00:00:00 开始到现在的秒数。系统基本数据类型
time_t
用于保存这种时间值。 - 进程时间:也被称为CPU时间,用以度量进程使用的CPU资源。其以时钟滴答计算。每秒钟曾经取为50、60或100个时钟滴答。使用
clock_t
保存这种时间值。
UNIX系统为每个进程维护了3个时间值:
- 时钟时间
- 用户CPU时间
- 系统CPU时间
时钟时间(wall clock time),是进程运行时间总量。
用户CPU时间是执行用户指令所用的时间量。同理系统CPU时间就是执行内核程序的时间。两者之和被称为CPU时间。
使用time
命令获取要执行的命令的三个时间。
系统调用和库函数
Linux 3.2.0 提供了380个系统调用,FreeBSD 8.0 提供的系统调用超过 450 个。
UNIX为每个系统调用在标准C库中设置一个具有同样名字的函数。从应用角度考虑,可将系统调用视为 C 函数(我怎么感觉说反了)。
多的不讲,一张图: