Linux 系统编程
传智播客-邢文鹏1
2014-09-27
1http://blog.csdn.net/itcastcpp
前言
学习目标
成为linux/unix系统程序员
学习态度
* 谦虚
* 严谨
* 勤思
* 善问
学习方法
从本章开始学习各种Linux系统函数,这些函数的用法必须结合Linux内核的工作原理
来理解,因为系统函数正是内核提供给应用程序的接口,而要理解内核的工作原理,必
须熟练掌握C语言,因为内核也是用C语言写的,我们在描述内核工作原理时必然要用“指
针”、“结构体”、“链表”这些名词来组织语言,就像只有掌握了英语才能看懂英文书一
样,只有学好了C语言才能看懂我描述的内核工作原理。读者看到这里应该已经熟练掌握了C
语言了,所以应该有一个很好的起点了。我们在介绍C标准库时并不试图把所有库函数讲一
遍,而是通过介绍一部分常用函数让读者把握库函数的基本用法,在掌握了方法之后,书上
没讲的库函数读者应该自己查Man Page学会使用。同样,本书的第三部分也并不试图把所有
的系统函数讲一遍,而是通过介绍一部分系统函数让读者理解操作系统各部分的工作原理,
在有了这个基础之后就应该能够看懂Man Page学习其它系统函数的用法。
读者可以结合[APUE2e]学习本书的第三部分,该书在讲解系统函数方面更加全面,但
对于内核工作原理涉及得不够深入,而且假定读者具有一定的操作系统基础知识,所以并
不适合初学者。该书还有一点非常不适合初学者,作者不辞劳苦,在N多种UNIX系统上做了
实验,分析了它们的内核代码,把每个系统函数在各种UNIX系统上的不兼容特性总结得非
常详细,很多开发者需要编写可移植的应用程序,一定爱死他了,但初学者看了大段大段
的这种描述(某某函数在4.2BSD上怎么样,到4.4BSD又改成怎么样了,在SVR4上怎么样,到
Solaris又改成怎么样了,现在POSIX标准是怎么统一的,还有哪些系统没有完全遵守POSIX
标准)只会一头雾水,不看倒还明白,越看越不明白了。也正因为该书要兼顾各种UNIX系
统,所以没法深入讲解内核的工作原理,因为每种UNIX系统的内核都不一样。而本书的侧重
点则不同,只讲Linux平台的特性,只讲Linux内核的工作原理,涉及体系结构时只讲x86平
台,对于初学者来说,绑定到一个明确的平台上学习就不会觉得太抽象了。当然本书的代码
也会尽量兼顾可移植性,避免依赖于Linux平台特有的一些特性。
只听不练肯定学不会Linux,每个知识点都需要去动手实践
目录
前言
目录
1 文件I/O
1.1 C标准函数与系统函数的区别 . . . . . . . . . . . . . . . . . . . . .
1.1.1 I/O缓冲区 . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2 效率 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.3 程序的跨平台性 . . . . . . . . . . . . . . . . . . . . . . .
1.2 PCB概念 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.1 task_struct结构体 . . . . . . . . . . . . . . . . . . . . . .
1.2.2 files_struct结构体 . . . . . . . . . . . . . . . . . . . . .
1.3 open/close . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.1 文件描述符 . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.2 最大打开文件个数 . . . . . . . . . . . . . . . . . . . . . .
1.4 read/write . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.5 阻塞和非阻塞 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.5.1 阻塞读终端 . . . . . . . . . . . . . . . . . . . . . . . . .
1.5.2 非阻塞读终端 . . . . . . . . . . . . . . . . . . . . . . . .
1.5.3 非阻塞读终端和等待超时 . . . . . . . . . . . . . . . . . . .
1.6 lseek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.7 fcntl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.7.1 用fcntl改变File Status Flag . . . . . . . . . . . . . . . . .
1.8 ioctl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.9 习题 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2 文件系统
2.1 ext2文件系统 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.1 目录中记录项文件类型 . . . . . . . . . . . . . . . . . . . .
2.1.2 数据块寻址 . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 stat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 chmod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.4 chown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5 utime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.6 truncate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.7 link . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.7.1 link
i
iii
1
1
1
1
1
2
2
2
2
2
4
5
6
6
8
9
9
10
10
11
12
15
15
16
17
17
18
18
19
19
19
19
2.7.2 symlink . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
2.7.3 readlink
2.7.4 unlink
. . . . . . . . . . . . . . . . . . . . . . . . . . .
2.8 rename . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9 chdir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10 getcwd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.11 pathconf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12 目录操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.1 mkdir . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.2 rmdir . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.3 opendir/fdopendir . . . . . . . . . . . . . . . . . . . . . .
2.12.4 readdir . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.5 rewinddir . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.6 telldir/seekdir . . . . . . . . . . . . . . . . . . . . . . .
2.12.7 closedir
. . . . . . . . . . . . . . . . . . . . . . . . . .
2.12.8 递归遍历目录 . . . . . . . . . . . . . . . . . . . . . . . .
2.13 VFS虚拟文件系统 . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
2.14 练习 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.1 dup/dup2
3 进程
3.1 进程环境 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 进程状态 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 进程原语 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.1 fork
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.2 exec族 . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.3 wait/waitpid
. . . . . . . . . . . . . . . . . . . . . . . .
3.4 练习 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4 进程间通信
4.1 pipe管道 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 fifo有名管道 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 内存共享映射 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.1 mmap/munmap . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.2 进程间共享通信 . . . . . . . . . . . . . . . . . . . . . . .
4.4 Unix Domain Socket . . . . . . . . . . . . . . . . . . . . . . . . .
4.5 习题 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5 信号
5.1 信号的概念 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.1.1 信号编号 . . . . . . . . . . . . . . . . . . . . . . . . . .
5.1.2 信号机制 . . . . . . . . . . . . . . . . . . . . . . . . . .
5.1.3 信号产生种类 . . . . . . . . . . . . . . . . . . . . . . . .
5.1.4 信号产生原因 . . . . . . . . . . . . . . . . . . . . . . . .
5.2 进程处理信号行为 . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3 信号集处理函数 . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
20
20
20
20
20
21
21
21
21
21
21
22
22
22
22
24
24
26
27
28
30
30
30
32
35
37
39
39
41
42
42
44
46
46
49
49
49
49
50
51
52
53
5.6.1 signal
5.4 PCB的信号集 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.4.1 sigprocmask . . . . . . . . . . . . . . . . . . . . . . . . .
5.4.2 sigpending
. . . . . . . . . . . . . . . . . . . . . . . . .
5.5 信号捕捉设定 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.5.1 利用SIGUSR1和SIGUSR2实现父子进程同步输出 . . . . . . . . . .
5.6 C标准库信号处理函数 . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
5.7 可重入函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.8 信号引起的竞态和异步I/O . . . . . . . . . . . . . . . . . . . . . .
5.8.1 时序竞态 . . . . . . . . . . . . . . . . . . . . . . . . . .
5.8.2 全局变量异步I/O . . . . . . . . . . . . . . . . . . . . . . .
5.8.3 可重入函数 . . . . . . . . . . . . . . . . . . . . . . . . .
5.8.4 避免异步I/O的类型 . . . . . . . . . . . . . . . . . . . . . .
5.9 SIGCHLD信号处理 . . . . . . . . . . . . . . . . . . . . . . . . . .
5.9.1 SIGCHLD的产生条件 . . . . . . . . . . . . . . . . . . . . . .
5.9.2 status处理方式 . . . . . . . . . . . . . . . . . . . . . . .
5.10 向信号捕捉函数传参 . . . . . . . . . . . . . . . . . . . . . . . . .
5.10.1 sigqueue
. . . . . . . . . . . . . . . . . . . . . . . . . .
5.10.2 sigaction . . . . . . . . . . . . . . . . . . . . . . . . . .
5.11 信号中断系统调用 . . . . . . . . . . . . . . . . . . . . . . . . . .
5.12 练习 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6 进程间关系
6.1 终端 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.1.1 网络终端 . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2 进程组 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3 会话 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7 守护进程
7.1 概念 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.3 习题 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8 线程
8.1 线程概念 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.1.1 什么是线程 . . . . . . . . . . . . . . . . . . . . . . . . .
8.1.2 线程和进程的关系 . . . . . . . . . . . . . . . . . . . . . .
8.1.3 线程间共享资源 . . . . . . . . . . . . . . . . . . . . . . .
8.1.4 线程间非共享资源 . . . . . . . . . . . . . . . . . . . . . .
8.1.5 线程优缺点 . . . . . . . . . . . . . . . . . . . . . . . . .
8.1.6 pthread manpage . . . . . . . . . . . . . . . . . . . . . . .
8.2 线程原语 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
8.2.1 pthread_create
8.2.2 pthread_self
8.2.3 pthread_exit
8.2.4 pthread_join
53
53
54
55
56
56
56
56
57
57
58
58
59
59
59
60
61
61
61
61
61
63
63
64
65
66
69
69
69
70
71
71
71
71
72
72
72
73
73
73
74
75
75
. . . . . . . . . . . . . . . . . . . . . . .
8.2.5 pthread_cancel
8.2.6 pthread_detach
. . . . . . . . . . . . . . . . . . . . . . .
8.2.7 pthread_equal . . . . . . . . . . . . . . . . . . . . . . . .
8.3 线程终止方式 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.4 线程属性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.4.1 线程属性初始化 . . . . . . . . . . . . . . . . . . . . . . .
8.4.2 线程的分离状态(detached state) . . . . . . . . . . . . . .
8.4.3 线程的栈地址(stack address) . . . . . . . . . . . . . . . .
8.4.4 线程的栈大小(stack size) . . . . . . . . . . . . . . . . .
8.4.5 线程属性控制实例 . . . . . . . . . . . . . . . . . . . . . .
8.5 NPTL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.6 细节注意 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.7 练习 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9 线程同步
9.1 线程为什么要同步 . . . . . . . . . . . . . . . . . . . . . . . . . .
9.2 互斥量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.2.1 临界区(Critical Section) . . . . . . . . . . . . . . . . .
9.2.2 临界区的选定 . . . . . . . . . . . . . . . . . . . . . . . .
9.2.3 互斥量实例 . . . . . . . . . . . . . . . . . . . . . . . . .
9.3 死锁 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.4 读写锁 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.5 条件变量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.6 信号量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.7 进程间锁 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.7.1 进程间pthread_mutex . . . . . . . . . . . . . . . . . . . . .
9.7.2 文件锁 . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.8 习题 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
77
78
78
79
79
79
80
81
81
82
83
83
85
86
86
86
87
87
88
88
89
90
92
92
93
94
10 网络基础
97
10.1 模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
10.1.1 OSI七层模型 . . . . . . . . . . . . . . . . . . . . . . . . .
97
10.1.2 TCP/IP四层模型 . . . . . . . . . . . . . . . . . . . . . . .
98
10.2 通信过程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
10.3 协议格式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
10.3.1 数据包封装 . . . . . . . . . . . . . . . . . . . . . . . . . 100
10.3.2 以太网帧格式 . . . . . . . . . . . . . . . . . . . . . . . . 100
10.3.3 ARP数据报格式 . . . . . . . . . . . . . . . . . . . . . . . . 101
10.3.4 IP段格式 . . . . . . . . . . . . . . . . . . . . . . . . . . 102
10.3.5 UDP数据抱格式 . . . . . . . . . . . . . . . . . . . . . . . . 103
10.3.6 TCP数据报格式 . . . . . . . . . . . . . . . . . . . . . . . . 105
10.4 再议TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
10.4.1 tcp状态转换图 . . . . . . . . . . . . . . . . . . . . . . . . 106
10.4.2 TCP流量控制(滑动窗口) . . . . . . . . . . . . . . . . . . . . 109
10.4.3 TCP半链接状态 . . . . . . . . . . . . . . . . . . . . . . . . 110
10.4.4 2MSL
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 110