首先给出一个APUE2e英文电子书的链接: http://book.chinaunix.net/special/ebook/addisonWesley/APUE2/大家可参照该书的内容来点评这一系列学习笔记。
这一章讲的是UNIX系统的一些基础知识,对后续各章中所要涉及到的知识做了个大概介绍。依照我的理解,这一章重点要掌握的是如下一些概念:系统调用和库函数,程序、进程和线程,出错处理,时间度量。至于其他概念如文件和目录,输入输出,信号等概念可粗略了解,因为后面的章节有很详细的介绍。
1、系统调用和库函数
系统调用:操作系统提供的可直接进入内核的接口。
库函数:在系统调用基础上开发的功能接口。
两者的区别:系统调用直接调用内核,功能简单,数量小(符合以“最简单的设计满足最大的效用”的设计原则),如read,write的就是系统调用。库函数:在系统调用的基础上,开发的提供较为复杂功能的接口,如库函数scanf和printf就是在系统调用(read和write)的基础上添加了缓冲控制等而实现的。
相同点:都为编程者提供现成的服务,从使用者的角度来说没有区别。
启示:C程序设计和unix环境编程的联系。C程序设计是一个语言层面的东西,我们所要做的就是利用它所提供的各种库函数来编程。但是这些库函数的实现必然是涉及到具体的平台的,它们的实现必然依赖于某具体平台的提供的系统调用。大家一定有这样的体会:在windows下用c编程,如果不使用windows提供的api,要编出个像样的程序是很难的,所以抛开具体环境谈编程(可移植并不是不考虑具体环境,而是在慎重考虑具体环境做出好的兼容性设计)无异于纸上谈兵。UNIX是一个具体环境,在其下用语言编程就是unix环境编程。关于这个问题,当我们在第二张章中讲述各标准(ISOC、POSIX.1和SUS)时,会有更深刻的体会。
2、程序、进程和线程
这个一般的操作系统系统教材上都有,简单地说一下。
程序和进程。程序是一个静态的概念,指的是可执行文件。当可执行文件被执行时,这个执行的实例就是进程。一个程序可能对应多个进程,如windows下记事本是一个程序,当你打开多个时它就运行了多个执行实例,即它对应了多个进程,这个可以用任务管理器验证。进程是多任务OS的概念,是为了提供并发性而提供的。
进程和线程。在不支持线程的os中,进程是cpu调度的单位,即某个进程要么运行,要么不运行。但是,对于某些具体问题,其内部有相对独立的部分A和B(如telnet终端,其读用户和读网络是两个较为独立的部分),在不支持线程的OS下,A的运行受B的影响(如A可能因B被阻塞而被阻塞)。在这样一种情况下,我们可将A和B分别作为一个cpu调度的单位,即分别以线程运行,但考虑到A和B相互之间交互比较多,共享的东西比较多,所以线程共享进程内的地址空间、文件描述符等资源。可以看出这个时候进程是资源分配的单位,而线程则是cpu调度的单位了。
3、出错处理
健壮性是程序的重要保证,而正确的出错处理是保证健壮性的一个重要环节。
C的传统出错处理方法有三种:返回一个状态码来表明成功或失败,把错误码赋值给一个全局标记并且让其他的函数来检测,终止整个程序。
第一种我们很常见,如malloc函数返回一个空指针来指示分配失败。
第二种在unix机制中很常见。unix进程用全局的变量errno(对于多线程环境,每个线程都有其局部的errno)来存储错误,不同的errno值代表不同的错误值(如errno等于EACESS代表权限不够,ENOENT代表文件或目路不存在)。我们可以用strerr或perror函数来检测errno值,并打印相应的错误信息。
第三种在C库中也很常见。我们可以用exit或abort来终止程序,这一般在程序遇到了致命性错误时才使用。exit与abort的不同在于前者会做一些清理性工作,如清空流、关闭文件等,而后者不做。
4、时间度量
Unix系统使用两种时间:日历时间和进程时间。时间度量很重要,因为我们的日志系统、文件系统等都以其为基础。
日历时间是自1970-01-01 00:00:00以来UTC(国际标准时间)所经过的秒数的累计值。日历时间是绝对时间,我们的文件修改时间等往往用它来记录。
进程时间是另一个我们接触得很多的时间。它以时钟嘀嗒来计算,历史上每秒钟曾取为50、60或100个嘀嗒,对于具体的系统我们可以用sysconf函数(第2章中讲述)来取得每秒钟所对应的时钟嘀嗒数。
UNIX系统的进程时间又分为三种:时钟时间、用户CPU时间和系统CPU时间。时钟时间是进程从开始到运行结束的时间总量,很显然它与系统当前的负荷有关。用户CPU时间是执行用户指令(非系统调用)所用的时间。系统CPU时间是执行内核调用所用的时间。用户CPU时间和系统CPU时间之和被统称为CPU时间。
我们常用进程时间特别是CPU时间来衡量程序的质量。如第五章就以它们为标准,比较了使用IO标准库(fgets和fputs等)的程序和直接使用系统调用(write、read等)的程序的性能差异。
5、习题
该章习题简单,需要注意的是1.4的答案是按新版本的出错处理机制(如习题答案所说的那种机制)给出的,而附录中给出的错误处理机制还是以前的老版本(errno并不需要保存)。
好,头晕晕的了,就写到这里了^_^