《Unix环境高级编程》学习笔记:从点到面

  以前在课堂上学习过《Unix初级教程(第四版)》,对于Unix有了一点了解。由于以后使用的需要,要对它进行比较深入的学习,为此需要阅读不少的书籍,这本《Unix环境高级编程》便在此列。希望能通过这本书了解Linux的API,并在这个过程中了解Linux系统的机制。书中内容丰富,有以前了解的,更多的是不了解的。作为第一次阅读,目的不在于事无巨细,过目不忘,而是有个大体了解,从点到面地熟悉这个系统。为了构建整体的印象,对已知的和刚刚了解的都有所涉及。同时作为笔记,不希望成为对目录的简单复制,而是能成为对学习的程度和体会的记录。

 

第一章  基础知识

  这一章本身就是概括,略。

 旧知:

  体系结构、登录、shell简介

 

第二章  UNIX标准化及实现

 旧知:

  ISO C、POSIX、系统实现(SVR4、4.4BSD、FreeBSD、Linux、Mac OS X、Solaris)

 新知:

  Single UNIX Specification(POSIX.1的一个超集)、各个标准作出的限制(sysconf、pathconf、fpathconf可以获得)

 

第三章  文件I/O

 旧知:

  文件描述符、文件I/O函数(open、creat、close、lseek、read、write以及可能造成的文件空洞)、I/O效率(缓冲区大小)、

  打开文件使用的数据结构(进程表项、文件表、v节点表)、原子操作

 新知:

  文件描述符的复制(dup和dup2)、及时手动更新缓冲区(sync、fsync、fdatasync)、获取和设置已打开的文件的性质(fcntl)

  另外从这一章起,逐渐发现和文件操作有关的同一种功能的函数经常有两个版本,前面带f的参数一般是文件描述符filedes,不带f的使用路径pathname。

 

第四章  文件和目录

 旧知:

  文件类型、用户ID和组ID、文件访问权限、权限的修改(chmod、fchmod)、文件长度(不含空洞情况)、基本操作(remove、rename、mkdir、rmdir)

 新知:

  查看文件属性(stat、fstat、lstat)、目录的读权限和执行权限、权限测试(access)、权限屏蔽字的设置(umask)、粘住位(如果支持,在交换区保护正文)、

  更改用户ID和组ID(chown、fchown、lchown)、文件截短、文件系统(i节点、数据块和目录块、目录文件和普通文件的不同)、

  硬链接(在原有知识之上,link、unlink的使用和具体操作、临时文件的删除)、符号链接(symlink、readlink、构成循环的符号链接)、文件时间的修改(utime)

  工作目录及更改(chdir、fchdir、getcwd)、设备特殊文件(st_dev和st_rdev的区别)

 

第五章  标准I/O库

 类似于涉及文件操作的一些函数,流操作的一些函数的也有三个版本:前缀s的把字符写入缓冲区buf,前缀f的写入指定流,不带前缀的写入到标准输入输出。这只是一个概括。

 旧知:

   流和FILE对象、标准输入、标准输出、标准出错、流的打开(fopen、freopen、fdopen)

   字符读(getc、fgetc、getchar和相关的ferror、feof、clearerr、ungetc)和写(putc、fputc、putchar)

   按行I/O(fgets、gets、fputs、puts)

   格式化I/O(printf、fprintf、sprintf、snprintf、scanf、fscanf、sscanf和一些其他变体)

 新知:

   标准I/O效率、二进制I/O(一次处理整个结构fread、fwrite)、定位流(ftell、fseek、rewind、ftello、fseeko)

   临时文件(创建和维护:tmpnam、tmpfile)

   标准I/O库实际并不完善,这和基本设计和不同的实现有关。不足之处之一是效率不高,软件包是一个代替方法。

 

第六章  系统数据文件和信息

 旧知:

   口令文件

 新知:

   阴影口令、组文件、附加组ID、登录账户记录、时间日期函数

 

 第七章  进程环境

  旧知:

   exit函数(exit、_exit和_Exit)、C程序存储空间布局、存储器分配(malloc、calloc、realloc)、环境变量、跨函数跳转(setjmp和longjmp)

 新知:

   atexit函数、环境表、共享库(库函数的动态链接,减小可执行文件长度)、进程资源限制(getrlimit和setrlimit函数)

 

第八章  进程控制

  旧知:

    进程标识符、fork()、exit()、wait()和waitpid()、竞争条件、exec()、

 新知:

    vfork()、waitid()、wait3和wait4、exec的六种形式和工作过程、更改用户ID和组ID、解释器文件(执行其第一行所指定的文件)、system()、

    进程会计(产生进程的各项运行记录)、用户标识、进程时间(不是很理解墙上时钟时间)

 对于程序清单8-9中使用的变量environ可以参考:http://topic.csdn.net/t/20060820/13/4962381.html

 

第九章  进程关系

 新知:

    终端登录过程、getty程序、进程组、会话、控制终端(与会话和进程组相关)、与前面三项相关联的tcgetpgrp、tcsetpgrp、tcgetsid

    作业控制(中断、退出、挂起;后台运行和转为前台)、孤儿进程组

    一个作业只是几个进程的集合,通常是一个进程的管道线。对于这章内容,之前只知道如何让程序后台运行(加&)和查看,其他方面了解的很少。

    9.9节shell执行程序想说明在不同版本的UNIX上shell执行程序的方式以及这和上面一些概念的关系,感觉自己的理解还是不到位。

 

第十章  信号

 旧知:

    signal()(告诉内核出现某个信号时应采取的操作)

 新知:

    可重入函数、一些信号语义、kill()和raise()、alarm()和pause()

    信号集和相关操作(sigemptyset、sigfillset、sigaddset、sigdelset、sigismember、sigprocmsak、sigpending、sigaction)

    sigsetjmp()和siglongjmp()、sigsuspend()、abort()与system()和sleep()在信号情景下的实现、作业控制信号

    对于信号,以往了解的比较少,这部分的阅读时间拖得也比较长,了解仍不够深入。目前只是对信号机制的作用方式有所了解,但读后感觉确实对于理解UNIX里的一些其它机制的实现有了不同的认识。

 

第十一章  线程

 旧知:

    线程标识tid、线程创建pthread_create()、线程终止pthread_exit()和相关的pthread_join()、线程同步之互斥量mutex

 新知:

    对同一个互斥量加锁两次会造成死锁(以前只知道两个线程循环请求的死锁);条件变量作为同步机制的应用

 

第十二章  线程管理

 新知:

    线程属性(分离状态、警戒缓冲区、线程栈低地址和大小、取消)、线程的同步对象属性(互斥量、读写锁)、线程级的函数重入、线程私有数据

    线程和信号(由同一个进程共享)、线程与fork和I/O

 

第十三章  守护进程

 新知:

    常见守护进程、创建守护进程、出错日志

    本章内容也是第一次了解,由于涉及信号处理,对于示例仍处于一知半解的状态。

 

第十四章  高级I/O

 新知:

    非阻塞I/O、记录锁、STREAMS、I/O多路转接的实现(select()、pselect()、poll())、异步I/O(涉及不同系统)

    readv和writev()、readn()和writen()、存储映射I/O:mmap()

    对于记录锁,以往知道一些,这里做了进一步了解。

    STREAMS只是大概了解了其功能和普通的流的差异,多路转接也是只做了简单了解。

    关于mmap、readn()、writen()与传统的read()&write()的性能差异书中亦有分析。

 

第十五章  进程间通信

  进程间通信即IPC,对于这章提到的管道、FIFO、消息队列、信号量和共享存储,以前有所了解。这章细节内容比较多,暂且根据目前的理解总结一下。

  管道只限于具有公共祖先的进程之间使用,使用方式:初始化管道->关闭不用的读或写端->数据传送。由管道的特性和使用方式,有相关的函数popen()和pclose()。协同进程的例子试了一试,加深了理解。

  FIFO是一种文件类型,文件I/O函数自然可以用于操作FIFO。

  除了管道和FIFO,后三种都属于XSI IPC,它们的相似处在于其IPC结构(标识符ID和键key、权限结构、结构限制),在系统范围内使用。它们的操作函数的格式比较类似:由key获得ID的msgget()、semget()、shmget();操作函数msgctl()、semctl()、shmctl()。消息队列和信号量还各有自己的特有结构:前者是消息,后者是信号量集和信号量。消息队列特有的操作:消息入队msgsnd()和出队msgrcv();信号量特有操作semop();共享存储特有操作:连接到地址空间shmat()、地址空间脱离shmdt()。

  书中信号量部分似乎漏了一行:信号量集是如何提供它所包含的信号量的入口的。在书中struct semid_ds中遗漏的一行如下:

 struct sem                *sem_base        /*指向集合中第一个信号量的地址*/

  参考了APUE的电子版(似乎是第一版)和这个帖子:http://bbs.chinaunix.net/thread-483853-1-1.html才有了上面的结论。个人认为如果是有意省略,确实不恰当。

第十六章  网络IPC:套接字

  对于套接字之前通过《TCP/IP Sockets编程(C语言实现) 》有所学习,这章对于作者来说是个复习。地址族、字节序、通用地址结构sockaddr、套接字地址sockaddr_in和一些相应的转换函数不必再提;查询配置信息的函数gethostent()、getnetent()、getprotoent()、getservent()和一些相关函数是第一次遇到,或许是因为它们是BSD网络软件提供的接口,简单的了解了一下。getaddrinfo()和getnameinfo()比较熟悉,也不细述。

  对于一些和套接字操作相关的函数,根据阅读和对程序清单的理解,大体使用方式简述为如下,

  客户机,创建并填充socket后,面向连接的需要先connect()后send()或recv();无连接不用connnect()而是直接使用sendto()和recvfrom()。sendmsg()和recvmsg()用于使用多重缓冲区进行消息传送,其参数不涉及destaddr,应该是面向连接的。

  服务器,创建并填充socket,先bind(),打开listen()。面向连接需要在收到请求后使用新的socket进行accept(),原socket继续侦听;无连接侦听到后即可使用原socket进行数据传输。使用函数和客户机一样,按是否面向连接选用。

  带外数据是一些通信协议所支持的可选特征。TCP仅支持一个字节的紧急数据,在普通数据传递机制数据流之外传输。这里涉及到信号发送和处理。

  recv()和send()涉及到非阻塞和异步I/O,其又与信号有关,行为和阻塞模式下不同,使用方法介绍的比较简单,不在此赘述。

 

第十七章  高级进程间通信

  本章主要介绍的是基于STREAMS的管道和域套接字这两种进程间通信方式,后面的实例即是对它们的使用。理解的还不够,目前还是一知半解的状态。

 

第十八至二十一章

  这四章分别介绍终端I/O、伪终端、数据库函数库、与网络打印机通信,前两者以前完全没接触过,现在仅仅了解基本概念;后两者是具体实现,源代码也没有研读。

 

  花了近两个月终于算是把这本书大体浏览了一遍,更加感到不了解的东西还很多,需要学习的东西还很多。

你可能感兴趣的:(unix)