学习是一种信仰。
分类: 其他UNIX
2010-04-25 19:23:31
第一章 概述
1.1 只有遵循XSI的实现才能称为UNIX系统.
1.2 UNIX向用户提供两种界面:用户界面。系统调用(用户编写程序时可以使用的界面)
1.3 操作系统的设计目标
用户观点:方便用户
资源观点:充分利用资源
方便用户和充分利用资源常常是矛盾的。操作系统就是要协调这对矛盾。
第二章 UNIX基础知识
2.1操作系统的启动经历三个过程:系统引导,核心初始化,系统的初始化
(1)把UNIX系统核心装入内存并且让它开始执行的工作叫做系统引导。
1)上电 、2)BIOS(保存在主板上的闪存中)检查系统硬件。
3)加载主引导程序,即(从硬盘0头,0道,1扇区)寻找/unix文件,并将该文件装入内存 4)内核装入程序将控制权交给新装入的内核从而使之得以运行。
(2)内核初始化
1)初始化少量的硬件接口、初始化系统时钟、初始化存储管理。还要初始化少量的数据结构。
2)初始化进程0 注:进程0没有代码段,它就是一个进程数据结构。
3)进程0创建进程1
(3)系统初始化
1)进程1执行系统调用exec,系统程序/sbin/init 读取配置文件/etc/inittab,按照其中的配置对系统进行初始化。激活交换分区,检查磁盘,加载硬件模块,启动对应运行级别的守护进程。
2)init为每一条通信线路创建一个getty进程来实现多用户方式。
3)等待用户注册,检查用户的登录口令建立shell进程。
4)当shell程序退出时,init程序就醒来,调用系统调用fork/exec产生一个新的getty程序来监督通信线路并等待下一个注册。
第三章 文件IO
3.1文件描述符:对于内核而言,所有打开文件都由文件描述符引用,文件描述符是一个非负整数。当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描述符。文件描述符0、1、2被代换成符号常数STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO 。惯例与内核无关.
3.2打开或创建文件:int open(const char *pathname, int flags, ... /*,mode_t mode*/);
FLAG参数:O_RDONLY ;只读打开。O_WRONLY 只写打开O_RDWR ;读写打开
①在这三个常量中应当必须且只能指定一个。
②open 返回的文件描述符一定是最小的未被使用的描述符。
3.3用close函数关闭一个打开文件 int close(int filedes);
(1)关闭一个文件时也释放该进程加在该文件上的所有记录锁
(2)当一个进程终止时,它所有的打开文件都由内核自动关闭。很多程序都使用这一功能而不显式地用close关闭打开的文件。
3.4 用来控制该文件的读写位置 off_t lseek (int filedes,off_t offset,int whence);
(1)lseek仅将当前的文件位移量记录在内核内,它并不引起任何I/O操作。然后,将该位移量用于下一个读或写操作。
(2)文件位移量可以大于文件的当前长度,在这种情况下,对该文件的下一次写将延长该文件,并在文件中构成一个空洞,位于文件中但没有写过的字节都被读为0。空洞不占用硬盘空间
(3)当whence 值为SEEK_CUR 或SEEK_END时,参数offet允许负值的出现
3.5 write函数向打开文件写数据ssize_t write(int filedes,const void *buff, size_t nbytes);
(1)把参数buff所指的内存写入nbytes个字节到参数filedes所指的文件内。文件读写位置也会随之移动
(2)其返回值通常与参数nbytes的值相同,否则表示出错。write出错的一个常见原因是:磁盘已写满,或者超过了对一个给定进程的文件长度限制
3.6预读技术:预测即将访问的页面,并提前把它们批量的读入缓存。
优点:I/O合并;延迟隐藏
3.7文件描述符标志和文件状态标志在作用范围方面的区别:前者只用于一个进程的一个描述符;后者则适用于指向该给定文件表项的任何进程中的所有描述符。
3.8原子操作(atomic operation)指的是由多步组成的操作,如果该操作原子地执行,则或者执行完所有步,或者一步也不执行,不可能只执行所有步的一个子集。
3.9 dup和dup2函数:复制一个现存的文件描述符
int dup(int oldfd); int dup2(int oldfd,int newfd);
(1)由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。用dup2则可以用newfd参数指定新描述符的数值。如果newfd已经打开,则先将其关闭。如若oldfd等于newfd ,则dup2返回newfd ,而不关闭它。
(2)与oldfd指向同一个文件,共享所有读写指针,和各项权限或标志位。
(3)这些函数返回的新文件描述符,与参数filedes共享同一个文件表项。
3.10 sync,fsync和fdatasync函数
延迟写减少了磁盘读写次数,但是却使得欲写到文件中的数据在一段时间内并没有写到磁盘上。当系统发生故障时,这种延迟可能造成文件更新内容的丢失。
为了保证磁盘上实际文件系统与缓冲区高速缓存中内容的一致性提供了以下三个函数。
int fsync(int fd) int fdatasync(int fd) void sync(void)
(1)sync函数只是将所有修改过的块缓冲区排入写队列,然后就返回,它并不等待实际写磁盘操作结束。通常称为update的系统守护进程会周期性地调用sync函数。这就保证了定期冲洗内核的块缓冲区。
(2)fsync函数只对由文件描述符filedes指定的单一文件起作用,并且等待写磁盘操作结束,然后返回。fsync可用于数据库这样的应用程序,这种应用程序需要确保将修改过的块立即写到磁盘上。
(3)fdatasync函数类似于fsync,但它只影响文件的数据部分。而除数据外,fsync还会同步更新文件的属性。
第四章 文件和目录
4.1文件系统
文件系统包括:引导块、超级块、索引节点表、数据块。
(1)每个文件系统各自对其i节点进行编号,故不能使一个目录项指向另一个文件系统的i节点。
(2)同文件系统下文件重命名(移动):文件内容未移动,只需构造一个指向现有i节点的新目录项,并解除与旧目录项的链接。
(3)任何一个叶目录的链接计数总是2:命名目录与目录中的.项。
(4)增加、删除一个文件操作。
4.2UNIX链接文件有软链接和硬链接两种链接文件。
(1)软链接(symbolic link)又叫符号链接。符号链接相当于Windows下的快捷方式。 指向一个文件的间接指针,里面包含着它所指向的文件的名字,系统看到软链接后自动跳到对应的文件位置处进行处理。
(2)硬链接为文件开设一个新的目录项,硬链接与原文件指向同一个inode。也就是说硬链接记录的是目标的 inode
(3)区别
区别1:建立命令选项不同
ln [option] source_file dist_file
ln -s source dist # 建立软链接
ln source dist # 建立硬链接
? 区别2:软链接可以跨文件系统,而硬链接只有在同一文件系统中的文件之间才能创建。
? 区别3:软链接可以对一个不存在的文件名进行链接 。
? 区别4:软链接可以对目录进行,但不允许给目录创建硬链接(有的系统支持)。
? 区别5:建立方式不同。软链接有自己的inode,并在磁盘上有一小片空间存放路径名,软链接文件属性为链接文件,硬链接文件只是增加了目录项,修改stat结构的st_nlink值,不占存储空间,硬链接文件是普通文件。
? 区别6: 删除链接文件时操作不同。对符号文件来说,只是删除符号文件对源文件无影响,对硬链接文件来说是减少链接计数值,当该值为0时删除源文件。但是删除源文件,符号文件就会找不到要指向的文件,而对硬链接来说不管你删除的是源文件还是链接文件,只要有一个存在,文件就存在。
4.3文件访问权限
1) 目录执行权限位。用名字打开任一类型的文件时,对该名字中包含的每一个目录,包括它可能隐含的当前工作目录都应具有执行许可权。目录执行许可权位常被称为搜索位。
例如:为了打开文件/ usr/include/stdio.h,需要具有对目录/, /usr, /usr/include 的执行许可权。
注意:目录的读许可允许我们获得目录中的文件清单. 可执行许可允许我们通过该目录而访问文件.
2) 文件的读许可权决定了我们是否能够打开该文件进行读操作。
3) 文件的写许可权决定了我们是否能够打开该文件进行写操作。
4) 在open函数中对文件指定O_TRUNC标志,须对该文件有写许可权。
5) 若要在一个目录中创建新文件,须对该目录具有写许可权和执行许可权。
6) 为了删除一个文件,必须对包含该文件的目录具有写许可权和执行许可权。对该文件本身则不需要有读、写许可权。
7) 如果用exec函数执行某个文件,必须对该文件具有执行许可权
进程每次打开、创建或删除一个文件时,内核对文件存取许可权进行测试:
(1)若进程的有效用户ID是0(超级用户),则允许存取。
(2)若进程的有效用户ID等于文件的所有者ID(即该进程拥有此文件):
(a)若适当的所有者存取许可权位被设置,则允许存取。(b)否则拒绝存取。
(3)若进程的有效组ID或进程的添加组ID之一等于文件的组ID:
– (a)若适当的组存取许可权位被设置,则允许存取。
– (b)否则拒绝存取。
(4)若适当的其他用户存取许可权位被设置,则允许存取,否则拒绝存取
按顺序执行这四步。注意: 如若进程拥有此文件,则按用户存取许可权批准或拒绝该进程对文件的存取——不查看组存取许可权。若进程并不拥有该文件,但进程属于某个适当的组,则按组存取许可权批准或拒绝该进程对文件的存取——不查看其他用户的存取许可权。
4.4 新文件和目录的所有权
新文件的用户ID设置为进程的有效用户ID。关于组ID, POSIX.1标准允许实现选择下列之一作为新文件的组ID:
(1)新文件的组ID可以是进程的有效组ID。
(2)新文件的组ID可以是它所在目录的组ID。
Linux 根据目录是否有 SGID 位确定新文件的组 ID. 若有 SGID 标志, 则新文件的组 ID 为所在目录的组 ID, 否则为进程的有效组 ID.
4.5 access函数
当用open函数打开一个文件时,内核以进程的有效用户ID和有效组ID为基础执行其存取许可权测试。access函数是按实际用户ID和实际组ID进行存取许可权测试的。
4.6 粘住位 S_ISVTX (saved-text bit)
保存交换后的可执行正文, 以便节省装入时间. 该标志已经没有多少实际意义.
对目录, 用来限制目录项的删除和重命名.
如果对一个目录设置了粘住位,则只有对该目录具有写许可权的用户并且满足下列条件之一,才能删除或更名该目录下的文件:
1)拥有此文件;2)拥有此目录; 3)是超级用户
4.7 link,unlink,remove和rename函数
unlink:为了删除一个现存的目录项,可以调用unlink函数
此函数删除目录项,并将由pathname所引用的文件的链接计数减1。如果该文件还有其他链接,则仍可通过其他链接存取该文件的数据。如果出错,则不对该文件作任何更改。
只有当连接计数达到0时,该文件的内容才可被删除。另一个条件也阻止删除文件的内容——只要有进程打开了该文件,其内容也不能删除。
remove函数可以解除对文件或者目录的链接
rename为文件或目录更名
如果newname已经存在:
? (1)rename(oldfile.dat newfile.dat), oldfile.dat是文件不是目录。若newfile.dat已存在,则先将该目录项删除然后将oldfile.dat更名为newfile.dat。
? (2) rename(olddir newdir), 如果newdir已存在,则它必须是空目录(只有.和..项), 先将其删除,然后将olddir更名为newdir。
? 此外,newname不能包含oldname作为其路径前缀。
– 例如:不能将/usr/foo更名为/usr/foo/testdir
? (3) 作为一个特例,如果oldname和newname引用同一文件,则函数不做任何更改而成功返。
? (4) 如果oldname或newname引用符号链接,则处理的是符号链接本身,而不是它所引用的文件
4.8 对某个目录具有存取许可权的任一用户都可读该目录,但是只有内核才能写目录,一个目录的写许可权位和执行许可权位决定了在该目录中能否创建新文件以及删除文件,它们并不表示能否写目录本身。
第五章 标准IO
5.1标准I/O与文件I/O的区别:
(1)标准I/O是ANSI C建立的一个标准I/O模型,具有一定的可移植性,文件I/O与操作系统相关。文件I/O属于低级I/O。
(2)标准I/O在系统调用基础上构建的,以优化长度执行I/O,默认采用了缓冲机制。文件I/O需要自己创建缓冲区。但unix系统中使用内核缓冲技术用于提高效率,读写调用是在内核缓冲区和进程缓冲区之间进行的数据复制。
(3)文件I/O主要针对文件操作,读写硬盘等,它操作的是文件描述符,标准I/O针对的是控制台,打印输出到屏幕等,它操作的是字符流。
5.2流
(1)是一个高度抽象的概念,它将数据的输入和输出看作是数据的流入和流出,当用标准I/O库打开或创建一个文件时,已使一个流与一个文件相结合,当打开一个流时,标准I/O函数fopen返回一个指向FILE对象的指针,它包含了I/O库为管理该流所需要的所有信息。
(2)对一个进程预定义了三个流,它们自动地可为进程使用:标准输入、标准输出和标准出错。
(3)标准 FILE 对象: stdin, stdout, stderror 与文件描述符STDIN_FILENO, STDOUT_FILENO 和 STDERR_FILENO 所引用的文件相同
(4)流定向:决定读写字符是单字节还是多字节可使用fwide函数进行设置(不改变已经定向的流的定向)
5.3冲洗(flush):在标准I/O库方面,冲洗意味着将缓存中的内容写到磁盘上。在终端驱动程序方面,刷新表示丢弃已存在缓存中的数据。
5.4缓冲机制
缓冲的目的:尽可能减少使用read和write调用的数量。
(1)完全缓冲
当填满标准I/O缓存后才进行实际I/O操作。对于驻在磁盘上的文件通常是由标准I/O库实施全缓冲的。
(2)行缓冲
当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。当流涉及一个终端时,典型地使用行缓存。
对于行缓存有两个限制:
第一个是:行缓冲的长度固定,不管是否遇到换行符,只要填满,就进行I/O操作。
第二个是:任何时候只要通过标准输入输出库要求从一个不带缓存的流,或者一个行缓存的流(它预先要求从内核得到数据)得到输入数据,那么就会造成冲洗所有行缓存输出流。
(3)不带缓冲
标准I/O库不对字符进行缓存。
如果用标准I/O函数写若干字符到不带缓存的流中,则相当于用write系统调用函数将这些字符写至相关联的打开文件上。
标准出错流stderr通常是不带缓存的,这就使得出错信息可以尽快显示出来,而不管它们是否含有一个新行字符
? UNIX 的默认缓冲:
– 标准错误无缓冲;
– 其他流如果是终端设备则为行缓冲;
– 否则为完全缓冲。
gets不能指定缓冲区的长度,会造成缓冲区溢出
5.5 缓冲文件系统(又称标准I/O):是指操作系统在内存中为每一个正在使用的文件开辟一个读写缓冲区。从内存向磁盘输出数据时,必须先送到内存缓冲区,装满缓冲区后才一起送到磁盘去。如果从向内存读入数据,则一次从磁盘文件将一批数据输入到内存缓冲区,然后再从内存缓冲区逐个地将数据送到程序数据区(变量)。ANSI C只采用缓冲文件系统
第六章 进程环境
exit()与_exit()区别
6.1进程终止
进程的终止有两种类型, 一种是正常终止, 一种是非正常终止.
正常终止包括:
1) main 函数返回 2)调用 exit 3)调用_exit或 _Exit.
4)最后一个线程从其启动例程返回5)最后一个线程调用pthread_exit
异常终止包括:
1) 调用abort 2)接收到一个信号并终止。 3)最后一个线程对取消请求做出响应
内核使程序执行的唯一方法是调用一个exec函数。进程自愿终止的唯一方法是显式或隐式地(调用exit )调用_ exit。进程也可非自愿地由一个信号使其终止。
6.2存储空间布局
6.3存储器分配
(1) malloc。分配指定字节数的存储区。初始值不确定。
(2) calloc。为指定长度的对象,分配能容纳其指定个数的存储空间。该空间中的每一位都初始化为0。
(3) realloc。更改以前分配区的长度(增加或减少)。当增加长度时,可能需将以前分配区的内容移到另一个足够大的区域,而新增区域内的初始值则不确定。
对齐问题,系统有关
注意事项:
? 调用sbrk可扩充或缩小进程空间,malloc和free不减小进程存储空间,保存在malloc池中,不返回给内核。
? 分配空间稍大于要求空间(管理信息)。
? 内存覆盖与内存泄露(未释放)。
6.4修改环境表
1)删除一个环境变量
先找到该指针,然后将所有后续指针都向首部移一个位置
2)修改一个环境变量
a) 新value的长度少于或等于现存value的长度
b)新value的长度大于原长度,则必须调用malloc为新字符串分配空间,然后将新字符写入该空间中,然后使环境表中针对name 的指针指向新分配区。
3)增加一个环境变量(第一次增加新name)
– 调用malloc为新的指针表分配空间
– 将原来的环境表复制到新分配区,并将指向新name = value的指针存在该指针表的表尾,然后又将一个空指针存在其后。
– 最后使environ指向新指针表。
注意:表中的大多数指针仍指向栈顶之上的各name = value字符串。
? 如果这不是第一次增加,只要调用realloc,以分配比原空间多存放一个指针的空间。然后将该指向新name = value字符串的指针存放在该表表尾,后面跟着一个空指针。
6.5进程资源限制
在更改资源限制时,须遵循下列三条规则:
(1) 任何一个进程都可将一个软限制更改为小于或等于其硬限制。
(2) 任何一个进程都可降低其硬限制值,但它必须大于或等于其软限制值。这种降低对普通用户而言是不可逆反的。
(3) 只有超级用户可以提高硬限制。
第七章 进程控制