APUE学习笔记

来源:互联网 发布:手机怎么看到淘宝账号 编辑:程序博客网 时间:2024/05/16 09:56

[在此处输入文章标题]

 

 

 

 

Chapter 1 UNIX System Overview

Unix 架构(程序员角度)

以上图形是重程序员的角度描述Unix的整体架构。最内层的实心圆是kernel(内核),我们的应用程序无法直接调用。Unix提供一组system calls(系统各调用),是我们的应用程序可以间接的访问Unix的内核程序。System calls也是就Unix提供的系统API,相当于Windows 32位操作系统中Win32 API。在外面一层是library routines,如标准C/C++库,POXIS线程库和其他一些标准库在不同平台上的实现,总而言之,如果是标准的,代码就可以不用修改,跨平台。Shell是一种特定的应用,通过命令行使用户调用system calls,在windows下面试CMD,在linux中就是terminator。最外面一层就是applications,也就是应用程序了,应用程序可以直接调用库函数(标准的或第三方的),同时也可以直接调用用system calls(也就是系统API),根据上面的现实,应用函数也可以调用shell

本章是对Unix系统的一个整体的描述,简单的介绍了I/O,文件系统,进程管理和用户管理等操作系统主要关心的问题,同时给出了一些小巧的Demo程序,是读者得到感性认识。我在学习本书时,使用的Ubuntu 9.04,装上了gccg++编译器,可以运行本章的Demo程序。

Chapter 2 UNIX Standards and Implementations

POISX是可移植操作系统接口,规定了Unix操作系统应该实现的借口。

匆忙的读完本章后,唯一直观的认识是以下四中OS提供Unix编程环境:

l  FreeBSD

l  Linux

l  Mac OS X

l  and Solaris

所以,我就可以安心在我的Ubuntu9.04中运行书中代码,来学习Unix环境编程了。本章的其他章节太多,太枯燥,现在读起来也没有什么感觉,我想当我通读完本书后在读此章,必有更多收获。

Chapter 3 File I/O

1 File操作的6个基本Unix系统函数

l  int open(filename, openFlag[readOnly/writeOnly/readAndWrite],…Mode)

Return file descriptor if OK, less-than-0 on error

l  int creat(filename, mode)

Return file descriptor opened for write-only if OK, less-than-0on error

l  int close(fileDescriptor)

Return 0 if OK, 1 on error

l  int lseek(fileDescriptor, offset, whence[relatively/absolutely/relativelyto the end])

//移动当前游标,方便随机访问文件。

Return new file offset if OK, 1 on error

l  int write(fileDescriptor, buffer, numberOfBytes)

Return number of bytes, or 0 if end of the file, 1 onerror

Notice: When reading from a regular file, if the endof file is reached before the requested number of bytes has been read. Forexample, if 30 bytes remain until the end of file and we try to read 100 bytes,read returns 30. The next time we call read, it will return 0 (end of file).

l  int read(fileDescriptor, buffer, numberOfBytes)

Return number of bytes if OK, 1 on error

Notice: The return value is usually equal to the nbytesargument; otherwise, an error has occurred. A common cause for a write error is either filling up a disk or exceeding the file size limitfor a given process.

          任务:将制定文件拷贝到另一个文件,并且在控制台上显示源文件内容。

2 本章后序小结阅读感受

自从阅读本章3.9节开始,我就觉得不是太明白。因为不向前面几节是通过API和代码描述,后面的这几节讲了一些机制,如IO效率,文件共享(并发访问文件),文件属性与进程的关系,文件数据同步等等。目前只有一个大体的影响,估计当第二次阅读此章时,会有不一样的感觉。不过,欣慰的是,本章我学会了调用UnixAPI对文件进行读写。

Chapter 4 Files and Directories

1.      第一遍通读感受。

上一张,主要重视是是如何操纵文件的内容,如读,写,游标控制等等。此章节,注重描述文件内容操作之外的关于文件的问题。如文件访问权限,目标(特殊的文件),快捷方式(特殊的文件),i-node,文件的用户ID和组ID等等。如果说上一章描述的是文件操作的功能性需求,这一张就是描述的文件操作的非空能性需求。这是第一遍通此章节的感受。

2.      Set-User-IDSet-Group-ID

每个进程有六个和他相关联的id,真实用户id、有效用户id、保存设置用户id以及三个对应的组id。注意的是这是与进程相关的,以前总是与文件所属用户ID弄混。

真实用户id是用户登录时使用的id

一般,有效用户id=真实用户id。例外是在文件模式字st_mode中置位一个特殊标记set-user-id,那么有效用户id就是此进程所执行的文件所属者的用户id。有用的是,判断一个文件是否可以被进程访问,是根据进程的有效用户id是否等于文件所属的用户id来的。举例:普通用户用程序passwd来修改密码时,会访问到root用户的文件/etc/passwd/etc/shadow。为什么能成功,是因为passwdset-user-id程序并且所属是root,当普通用户执行时,它的有效用户id就变成root,就可以访问上面两个文件。

3.      V-NodeI-Node

v-node是文件打开时存在的,i-node是文件存储在文件系统中用来描述文件的。

4.      Dot Dot Dot

在使用readdir系统函数遍历当前文件夹的时候,会将影藏文件读取,同时还会读取dotdot dot文件夹,会多读这两个文件夹,所以,有时候需要将他们提出掉。

5.      实现了linux下的非递归遍历文件夹。

Chapter 5 Standard I/O Library

Unix提供的标准输入输出函数中分为三大类:

l  一次处理一个字符

l  一次处理一行字符

l  一次处理固定缓存大小的字符

缓存的大小设置对效率的影响十分之巨大,应为会直接导致磁盘与内存数据交换的次数。

Chapter 6 System Data Files and Information

本章描述了如何以统一方式访问系统的密码,用户组文件。他们都有类是的便利方式和查找方式,使用的set, getend三部曲的方式。同时,讲解了如何获取当前系统时间,如何表示,下面的一张表十分有用,形象的说明的系统时间的使用:

Chapter 7 Process Environment

本章是具体讲进程控制的准备章节,简要的介绍了一个C程序的开始,结束,运行过程中在内存中的结构等等。

C Program Logic Memory Layout

C Program Start & End

 

Chapter 8 Process Control

1.      Fork函数的用法

今天使用了fork函数,就是衍生出子进程。在上SB梁怡雯的课时,就听说过这个函数,他的用法的确与众不同。它是将调用进程的内存中的结构复制了一份给子进程,所以栈、变量、堆等结构都是父亲的拷贝,所以子进程会接着调用的地方继续运行,所以为了在一个程序中写出两个进程的逻辑,使用if判断返回值是否为0Fork会调用两次返回,在父进程中返回子进程id,在子进程中返回0。所以,在返回0的条件下,执行子进程逻辑。在两个进程执行的先后顺序是不确定的,所以需要同步机制。本章前9节介绍了wait函数同步,同时提到了信号量同步,不过在10章才会详细介绍信号量。

2.      Real user id, effect user id,saved set-user-id Real group id, effectgroup id, saved set-group-id

以上的两组id的关系还不是很清楚,但是我知道他们是对进程权限控制的重要数据结构,所以以后找个时间,研究一下他们的使用方法。现在记住一点,他们与权限控制有关。

3.      Exce函数

该函数有6中变型,总的功能就是在心的process中执行指定的程序,该程序是编写好的可执行程序,这样就提供了一种多进程协作编程的环境。

Chapter 9 Process Relationships

本章讲了session, processgroup, job control, foreground & background process. 不过看的不是太明白,第二次阅读时,应该会有进一步的体会。

Chapter 10 Signals

本章详细的描述了信号量在进程间作用。你可以这样看待信号量,他好比一个信号弹,发射该信号弹的和接受信号弹的都是进程。信号弹有不同类型,本章中讲了31中,但是不同平台下,还是稍有不同。接受到信号弹后,接受进程可以对一些想应的工作。这需要使用signal函数注册处理方式,有忽略、默认或自定义函数。总觉得信号机制有点像设计模式中的观察着模式,信号发送进程是主题,信号接受进程是观察者。Unix提供这样一套信号机制,是为了使进程间存在一种通讯的机制,这样一个进程就有方法和另一个进程通信,虽然通信的媒介(signal)略显简陋,就是一些整数。

在阅读这一个章节时,我还学到了一个读书的方法。应为本章很长,估计是全书中最长的章节。我第一次阅读时,总是忘记了前面讲的概念,所以总有一种错觉,认为什么都没有学到。可是,当第二次阅读时,并且在忘记概念的时候往回翻阅,这些概念就自然记住了。所以,第一遍读书,即使什么都不记得,还不要紧,只要你在读一遍,第一遍的工作就没有浪费,但是如果你不读第二遍,那么第一遍的工作就浪费了。

Chapter 11 Threads

线程与进程同样提供了同样的工作模式——多任务模式。但是,线程是轻量级的,他不用消耗很多额外的内存资源,因为多线程共享一个进程程序的内存。本章,介绍了如何创建线程,销毁线程,如何获取线程id等相关的线程操作。同时,介绍了三种基本线程同步机制——互斥锁,读写锁和条件变量。

Chapter 12 Thread Control

本章描述了线程的属性设置,其他的没有仔细看。

Chapter 13 Daemon Processes

本章讲了一些Unix中守护进程(后台进程)的知识。觉得没有什么用处,没有仔细看,如果以后遇到相关的问题,可以回来看。

Chapter 14 Advanced IO

快速翻阅

Chapter 15 Interprocess Communication

快速翻阅

总结:

到今天为止(2009-12-24),通过两个月,我将这本书大概的浏览了一下,的却受益匪浅。这本书,通过以程序员的观点,全面解析了Unix系统以及衍生系统(Linux, Solaris, Mac OS, FreeBSD)的种种特性,这些特性都是计算机操作系统原理的一种实现。现在,我对计算机程序又有了进一步的认识。比如,我知道程序在内存中的逻辑结构,进程之间的关系与同步机制,信号量在进程之间的通信作用,管道在进程间的通信作用等等。Unix的整体系统调用也是通过C语言提供的API,和windows类是。对与IO的理解也进了一步,比如,因为内外存数据交换对性能造成很大影响,所以必须使用缓存机制,减少内外存数据交换,这样提高性能。计算机终端,只不过是I/O的一种特例,文件系统I/O,进程间的I/O都是IO家族中的一员。还发现,win 32 sockAPIUnix的十分类是,有种似曾相识的感觉,回想起一句话,win 32 sock 是直接从Berkeley socket 照搬过来的,这样才知道了为何有似曾相识的感觉。C/C++在不同平台上的实现,也都是通过各个平台的本地系统API实现的,他们也是提供了另一个跨平台的接口。论效率,还是各个平台本地API的效率最高。但是,用标准风转一层,就可以提高开发效率,因为不同平台间,不需要在此开发,或只需要少量的改动就可以了,这也是开发效率和运行效率的权衡。[在此处输入文章标题]

 

 

 

 

Chapter 1 UNIX System Overview

Unix 架构(程序员角度)

以上图形是重程序员的角度描述Unix的整体架构。最内层的实心圆是kernel(内核),我们的应用程序无法直接调用。Unix提供一组system calls(系统各调用),是我们的应用程序可以间接的访问Unix的内核程序。System calls也是就Unix提供的系统API,相当于Windows 32位操作系统中Win32 API。在外面一层是library routines,如标准C/C++库,POXIS线程库和其他一些标准库在不同平台上的实现,总而言之,如果是标准的,代码就可以不用修改,跨平台。Shell是一种特定的应用,通过命令行使用户调用system calls,在windows下面试CMD,在linux中就是terminator。最外面一层就是applications,也就是应用程序了,应用程序可以直接调用库函数(标准的或第三方的),同时也可以直接调用用system calls(也就是系统API),根据上面的现实,应用函数也可以调用shell

本章是对Unix系统的一个整体的描述,简单的介绍了I/O,文件系统,进程管理和用户管理等操作系统主要关心的问题,同时给出了一些小巧的Demo程序,是读者得到感性认识。我在学习本书时,使用的Ubuntu 9.04,装上了gccg++编译器,可以运行本章的Demo程序。

Chapter 2 UNIX Standards and Implementations

POISX是可移植操作系统接口,规定了Unix操作系统应该实现的借口。

匆忙的读完本章后,唯一直观的认识是以下四中OS提供Unix编程环境:

l  FreeBSD

l  Linux

l  Mac OS X

l  and Solaris

所以,我就可以安心在我的Ubuntu9.04中运行书中代码,来学习Unix环境编程了。本章的其他章节太多,太枯燥,现在读起来也没有什么感觉,我想当我通读完本书后在读此章,必有更多收获。

Chapter 3 File I/O

1 File操作的6个基本Unix系统函数

l  int open(filename, openFlag[readOnly/writeOnly/readAndWrite],…Mode)

Return file descriptor if OK, less-than-0 on error

l  int creat(filename, mode)

Return file descriptor opened for write-only if OK, less-than-0on error

l  int close(fileDescriptor)

Return 0 if OK, 1 on error

l  int lseek(fileDescriptor, offset, whence[relatively/absolutely/relativelyto the end])

//移动当前游标,方便随机访问文件。

Return new file offset if OK, 1 on error

l  int write(fileDescriptor, buffer, numberOfBytes)

Return number of bytes, or 0 if end of the file, 1 onerror

Notice: When reading from a regular file, if the endof file is reached before the requested number of bytes has been read. Forexample, if 30 bytes remain until the end of file and we try to read 100 bytes,read returns 30. The next time we call read, it will return 0 (end of file).

l  int read(fileDescriptor, buffer, numberOfBytes)

Return number of bytes if OK, 1 on error

Notice: The return value is usually equal to the nbytesargument; otherwise, an error has occurred. A common cause for a write error is either filling up a disk or exceeding the file size limitfor a given process.

          任务:将制定文件拷贝到另一个文件,并且在控制台上显示源文件内容。

2 本章后序小结阅读感受

自从阅读本章3.9节开始,我就觉得不是太明白。因为不向前面几节是通过API和代码描述,后面的这几节讲了一些机制,如IO效率,文件共享(并发访问文件),文件属性与进程的关系,文件数据同步等等。目前只有一个大体的影响,估计当第二次阅读此章时,会有不一样的感觉。不过,欣慰的是,本章我学会了调用UnixAPI对文件进行读写。

Chapter 4 Files and Directories

1.      第一遍通读感受。

上一张,主要重视是是如何操纵文件的内容,如读,写,游标控制等等。此章节,注重描述文件内容操作之外的关于文件的问题。如文件访问权限,目标(特殊的文件),快捷方式(特殊的文件),i-node,文件的用户ID和组ID等等。如果说上一章描述的是文件操作的功能性需求,这一张就是描述的文件操作的非空能性需求。这是第一遍通此章节的感受。

2.      Set-User-IDSet-Group-ID

每个进程有六个和他相关联的id,真实用户id、有效用户id、保存设置用户id以及三个对应的组id。注意的是这是与进程相关的,以前总是与文件所属用户ID弄混。

真实用户id是用户登录时使用的id

一般,有效用户id=真实用户id。例外是在文件模式字st_mode中置位一个特殊标记set-user-id,那么有效用户id就是此进程所执行的文件所属者的用户id。有用的是,判断一个文件是否可以被进程访问,是根据进程的有效用户id是否等于文件所属的用户id来的。举例:普通用户用程序passwd来修改密码时,会访问到root用户的文件/etc/passwd/etc/shadow。为什么能成功,是因为passwdset-user-id程序并且所属是root,当普通用户执行时,它的有效用户id就变成root,就可以访问上面两个文件。

3.      V-NodeI-Node

v-node是文件打开时存在的,i-node是文件存储在文件系统中用来描述文件的。

4.      Dot Dot Dot

在使用readdir系统函数遍历当前文件夹的时候,会将影藏文件读取,同时还会读取dotdot dot文件夹,会多读这两个文件夹,所以,有时候需要将他们提出掉。

5.      实现了linux下的非递归遍历文件夹。

Chapter 5 Standard I/O Library

Unix提供的标准输入输出函数中分为三大类:

l  一次处理一个字符

l  一次处理一行字符

l  一次处理固定缓存大小的字符

缓存的大小设置对效率的影响十分之巨大,应为会直接导致磁盘与内存数据交换的次数。

Chapter 6 System Data Files and Information

本章描述了如何以统一方式访问系统的密码,用户组文件。他们都有类是的便利方式和查找方式,使用的set, getend三部曲的方式。同时,讲解了如何获取当前系统时间,如何表示,下面的一张表十分有用,形象的说明的系统时间的使用:

Chapter 7 Process Environment

本章是具体讲进程控制的准备章节,简要的介绍了一个C程序的开始,结束,运行过程中在内存中的结构等等。

C Program Logic Memory Layout

C Program Start & End

 

Chapter 8 Process Control

1.      Fork函数的用法

今天使用了fork函数,就是衍生出子进程。在上SB梁怡雯的课时,就听说过这个函数,他的用法的确与众不同。它是将调用进程的内存中的结构复制了一份给子进程,所以栈、变量、堆等结构都是父亲的拷贝,所以子进程会接着调用的地方继续运行,所以为了在一个程序中写出两个进程的逻辑,使用if判断返回值是否为0Fork会调用两次返回,在父进程中返回子进程id,在子进程中返回0。所以,在返回0的条件下,执行子进程逻辑。在两个进程执行的先后顺序是不确定的,所以需要同步机制。本章前9节介绍了wait函数同步,同时提到了信号量同步,不过在10章才会详细介绍信号量。

2.      Real user id, effect user id,saved set-user-id Real group id, effectgroup id, saved set-group-id

以上的两组id的关系还不是很清楚,但是我知道他们是对进程权限控制的重要数据结构,所以以后找个时间,研究一下他们的使用方法。现在记住一点,他们与权限控制有关。

3.      Exce函数

该函数有6中变型,总的功能就是在心的process中执行指定的程序,该程序是编写好的可执行程序,这样就提供了一种多进程协作编程的环境。

Chapter 9 Process Relationships

本章讲了session, processgroup, job control, foreground & background process. 不过看的不是太明白,第二次阅读时,应该会有进一步的体会。

Chapter 10 Signals

本章详细的描述了信号量在进程间作用。你可以这样看待信号量,他好比一个信号弹,发射该信号弹的和接受信号弹的都是进程。信号弹有不同类型,本章中讲了31中,但是不同平台下,还是稍有不同。接受到信号弹后,接受进程可以对一些想应的工作。这需要使用signal函数注册处理方式,有忽略、默认或自定义函数。总觉得信号机制有点像设计模式中的观察着模式,信号发送进程是主题,信号接受进程是观察者。Unix提供这样一套信号机制,是为了使进程间存在一种通讯的机制,这样一个进程就有方法和另一个进程通信,虽然通信的媒介(signal)略显简陋,就是一些整数。

在阅读这一个章节时,我还学到了一个读书的方法。应为本章很长,估计是全书中最长的章节。我第一次阅读时,总是忘记了前面讲的概念,所以总有一种错觉,认为什么都没有学到。可是,当第二次阅读时,并且在忘记概念的时候往回翻阅,这些概念就自然记住了。所以,第一遍读书,即使什么都不记得,还不要紧,只要你在读一遍,第一遍的工作就没有浪费,但是如果你不读第二遍,那么第一遍的工作就浪费了。

Chapter 11 Threads

线程与进程同样提供了同样的工作模式——多任务模式。但是,线程是轻量级的,他不用消耗很多额外的内存资源,因为多线程共享一个进程程序的内存。本章,介绍了如何创建线程,销毁线程,如何获取线程id等相关的线程操作。同时,介绍了三种基本线程同步机制——互斥锁,读写锁和条件变量。

Chapter 12 Thread Control

本章描述了线程的属性设置,其他的没有仔细看。

Chapter 13 Daemon Processes

本章讲了一些Unix中守护进程(后台进程)的知识。觉得没有什么用处,没有仔细看,如果以后遇到相关的问题,可以回来看。

Chapter 14 Advanced IO

快速翻阅

Chapter 15 Interprocess Communication

快速翻阅

总结:

到今天为止(2009-12-24),通过两个月,我将这本书大概的浏览了一下,的却受益匪浅。这本书,通过以程序员的观点,全面解析了Unix系统以及衍生系统(Linux, Solaris, Mac OS, FreeBSD)的种种特性,这些特性都是计算机操作系统原理的一种实现。现在,我对计算机程序又有了进一步的认识。比如,我知道程序在内存中的逻辑结构,进程之间的关系与同步机制,信号量在进程之间的通信作用,管道在进程间的通信作用等等。Unix的整体系统调用也是通过C语言提供的API,和windows类是。对与IO的理解也进了一步,比如,因为内外存数据交换对性能造成很大影响,所以必须使用缓存机制,减少内外存数据交换,这样提高性能。计算机终端,只不过是I/O的一种特例,文件系统I/O,进程间的I/O都是IO家族中的一员。还发现,win 32 sockAPIUnix的十分类是,有种似曾相识的感觉,回想起一句话,win 32 sock 是直接从Berkeley socket 照搬过来的,这样才知道了为何有似曾相识的感觉。C/C++在不同平台上的实现,也都是通过各个平台的本地系统API实现的,他们也是提供了另一个跨平台的接口。论效率,还是各个平台本地API的效率最高。但是,用标准风转一层,就可以提高开发效率,因为不同平台间,不需要在此开发,或只需要少量的改动就可以了,这也是开发效率和运行效率的权衡。