APUE 笔记

Posted by lan_cyl on August 1, 2016

目录项

目录(directory)是一个包含目录项的文件。逻辑上可以认为每个目录项包含一个文件名,和说明该文件属性的信息。

目录项的逻辑视图与实际存放在磁盘上的方式是不同的。UNIX文件系统的大多数实现并不在目录项中存放属性,这是因为一个文件具有多个硬链接时,很难保持多个属性副本之间的同步。

信号

信号(signal)用于通知进程发生了某种情况。

键盘上通过中断键(interrupt key,通常是Delete或Ctrl+C)和退出键(quit key,通常是Ctrl+\)中断当前运行进程。

也可以调用kill()函数,向另一个进程发送信号。但是必须是该进程的所有者或者超级用户。

进程有3中处理信号的方式: 1. 忽略,不推荐 2. 按系统默认方式处理 3. 提供自编函数,捕捉并处理该信号

时钟时间、用户CPU、系统CPU

时钟时间:进程从开始运行到结束,时钟走过的时间,包括进程在阻塞和等待状态的时间

用户CPU时间:进程执行用户指令所用的时间

系统CPU时间:进程执行内核指令所用的时间

$ time  ./a.out

real    0m4.019s           //时钟时间
user    0m0.004s           //用户CPU时间
sys     0m0.000s           //系统CPU时间

关于第三章“不带缓冲的I/O的意思”

所有磁盘I/O都要经过内核的块缓存区,所有read write的数据也会被内核缓存。这里说read write是“不带缓冲的I/O”指的是用户进程不对两个函数自动缓冲,每次都要进行系统调用。

对 图3-6 Linux上用不同缓冲长度进行read操作的时间结果 说明 1. 当BUFFSIZE为1-32时,需要进行频繁的系统调用,所以用户CPU时间、系统CPU时间、时钟时间都比较大。 2. 当BUFFSIZE大于32时,时钟时间主要受磁盘I/O影响,由于大多数文件系统对磁盘I/O进行内核块缓存区,所以磁盘I/O的次数大致一样,时钟时间大致一样。

对 图5-6 使用标准I/O例程(fgets/fputs/getc/putc/fgetc/fputc)得到的实验结果 说明 1. 都比3-6最佳read版差,原因是循环次数大,fgets每次读一行、getc每次读一个字符。 2. 比3-6单字节read版好几十倍,标准I/O在用户进程内使用缓冲区。每次陷入内核read,不仅仅读取一行或者一个字节。 3. 系统CPU时间几乎相同,说明陷入内核态的次数及磁盘读写的次数几乎相同。用户缓冲区使得进程不用频繁陷入内核,内核缓冲区使得read调用不用频繁做磁盘I/O。

总结

内核块缓存区:减少read/write系统调用进行磁盘I/O的次数。

用户缓冲区:减少读取数据时进行系统调用的次数。

追加标志O_APPEND对文件读写的影响

  1. 仍然可以使用lseek和read函数读文件中任意一个位置的内容
  2. write函数在写数据之前会自动将文件偏移量设置为文件尾,所以写文件时只能在文件尾端开始。

文件模式字:设置用户ID位、设置组ID位

当执行一个程序文件时,进程的有效用户ID通常就是实际用户ID,有效组ID通常就是实际组ID,但是 1. 设置了set-user-ID位时,进程的有效用户ID为程序文件的所有者的用户ID 2. 设置了set-group-ID位时,进程的有效组ID为程序文件的组所有者ID

设置用户ID位、设置组ID位 都包含在stat.st_mode值中。可分别用常量S_ISUID/S_ISGID测试。

新文件和目录的所有权

新文件和目录的所有权规则一样。

  1. 新文件的用户ID设置位进程的有效用户ID。
  2. 新文件的组ID可以是
    • 进程的有效组ID
    • 新文件所在目录的组ID

组ID的设置规则:FreeBSD 8.0和Mac OS X 10.6.8默认使用新文件所在组的ID;Linux和Solaris需要检查新文件所在目录的设置组ID位,如果该目录的这一位被设置,则新文件的组ID设置为目录的组ID。

文件访问权限检查

open函数打开一个文件时,内核按进程的有效用户ID和有效组ID为基础执行访问权限测试

access和faccessat函数是按实际用户ID和实际组ID进行访问权限测试

访问权限测试步骤,access函数将有效ID换成实际ID来测试: 1. 若进程的有效用户ID为0(超级用户),则允许 2. 若进程的有效用户ID等于文件的所有者ID,那么如果所有者适当的访问权限位被设置,则允许 3. 若进程的有效组ID或者附属组ID之一等于文件的组ID,那么如果组适当的访问权限位被设置,则允许 4. 若其他用户适当的访问权限位被设置,则允许

文件系统

马丹,比哪个博客说的都清楚。P91,4.14节的图很清楚。

以下章节先跳过

7 进程环境

C语言中全局变量、局部变量、静态全局变量、静态局部变量比较

C++的作用域:全局作用域、局部作用局、语句作用域、类作用域、命名空间作用域、文件作用域 1. 全局变量具有全局作用域,只需在一个源文件中定义,就可以作用于所有源文件。 2. 静态全局变量也具有全局作用域,与全局变量的区别在于如果包含多个文件的话,它作用于定义它的文件里。 3. 静态局部变量具有局部作用域,只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,只对定义自己的函数体始终可见。 4. 局部变量也只有局部作用域,它是自动对象(auto),在程序运行期间不是一直存在的,函数一次调用执行结束后,就被撤销,所占用内存也被回收。

从分配内存空间看: 1. 全局变量、静态局部变量、静态全局变量都在静态存储区分配空间 2. 而局部变量在栈里分配空间

8 进程控制

### 9 进程关系 ### 10 信号

进程捕捉到信号并对其进行处理时,进程所执行的正常指令序列就被信号处理函数临时中断,它首先执行该信号处理程序中的指令。如果从信号处理程序返回(例如没有调用exit或longjmp),则继续执行在捕捉到信号时正在执行的正常指令序列(这类似于发生硬件中断时所做的)。

11 线程

### 12 线程控制 ### 13 守护进程 ### 14 高级I/O

  1. 非阻塞I/O
  2. 记录锁
  3. I/O多路转接——select和poll函数
  4. 异步I/O(aio_read/aio_write…)
  5. readv和writev函数
  6. 存储映射I/O(mmmap)

Creative Commons License
This work is licensed under a CC A-S 4.0 International License.