0 00:00:00,000 --> 00:00:06,960 1 00:00:07,000 --> 00:00:10,720 下面我们来讨论线程 2 00:00:10,760 --> 00:00:13,320 在刚才我们讨论进程的时候呢 3 00:00:13,360 --> 00:00:16,840 每个进程内部它的指令执行呢 4 00:00:16,880 --> 00:00:20,080 是有一个叫指令指针的寄存器来描述 5 00:00:20,120 --> 00:00:22,680 当前这个进程执行到什么地方 6 00:00:22,720 --> 00:00:25,480 但是在我们实际使用的时候呢 7 00:00:25,520 --> 00:00:28,960 一个进程内部我也可能会希望 8 00:00:29,000 --> 00:00:30,640 它有更好的并发性 9 00:00:30,680 --> 00:00:31,880 那这就是我们在这里 10 00:00:31,920 --> 00:00:33,800 引入线程的原因 11 00:00:33,840 --> 00:00:35,280 那在这儿我们先讨论 12 00:00:35,320 --> 00:00:37,480 引入线程我们通过一个实例来说 13 00:00:37,520 --> 00:00:39,160 为什么我们要在一个进程内部 14 00:00:39,200 --> 00:00:41,920 再进一步提高它的并发性 15 00:00:41,960 --> 00:00:45,320 好 然后说什么是一个线程 16 00:00:45,360 --> 00:00:47,000 在这儿呢我们给入这样一个例子 17 00:00:47,040 --> 00:00:48,880 说我有一个应用 18 00:00:48,920 --> 00:00:52,240 这个应用呢是播放音频的 MP3 19 00:00:52,280 --> 00:00:54,920 那它的功能呢包括这样几个方面 20 00:00:54,960 --> 00:00:57,560 一个呢是说我从音频文件里头 21 00:00:57,600 --> 00:00:59,600 读出相应的数据 22 00:00:59,640 --> 00:01:00,600 然后通常情况下 23 00:01:00,640 --> 00:01:03,320 我们的音频文件是压缩的 24 00:01:03,360 --> 00:01:05,640 然后我需要对数据进行解压 25 00:01:05,680 --> 00:01:06,800 解压之后呢 26 00:01:06,840 --> 00:01:09,560 我送到声卡去进行播放 27 00:01:09,600 --> 00:01:11,480 这是它要进行的三步 28 00:01:11,520 --> 00:01:14,080 这三步呢我们怎么来实现呢 29 00:01:14,120 --> 00:01:15,680 这个地方给出了一种 30 00:01:15,720 --> 00:01:18,680 用单进程的方式来实现的 31 00:01:18,720 --> 00:01:20,320 也就是说我在这个进程内部呢 32 00:01:20,360 --> 00:01:21,480 做了一个循环 33 00:01:21,520 --> 00:01:23,400 这个循环里头呢读数据 34 00:01:23,440 --> 00:01:26,680 解压然后播放一步一步来 35 00:01:26,720 --> 00:01:28,600 这个程序能很好的工作吗 36 00:01:28,640 --> 00:01:30,160 那你说我在这里头 37 00:01:30,200 --> 00:01:31,920 读磁盘足够速度快 38 00:01:31,960 --> 00:01:33,600 然后解压足够速度快 39 00:01:33,640 --> 00:01:35,840 那我解压完了之后给这边播放 40 00:01:35,880 --> 00:01:37,560 播放还没有播放完之前 41 00:01:37,600 --> 00:01:39,000 我下一部分的解压数据 42 00:01:39,040 --> 00:01:39,920 能跟得上的话 43 00:01:39,960 --> 00:01:42,120 这个程序是可以很好工作的 44 00:01:42,160 --> 00:01:44,240 但是如果说你细看下去的话 45 00:01:44,280 --> 00:01:46,000 这个程序会在什么地方有问题呢 46 00:01:46,040 --> 00:01:47,200 第一部分它需要 47 00:01:47,240 --> 00:01:51,000 频繁的进行IO操作 进行读写 48 00:01:51,040 --> 00:01:52,360 而第二部分呢 49 00:01:52,400 --> 00:01:54,800 解压它主要是用CPU来算 50 00:01:54,840 --> 00:01:56,960 这两个部分呢是交替进行的 51 00:01:57,000 --> 00:01:58,920 实际上我们在系统里呢 52 00:01:58,960 --> 00:02:00,040 这两个部分是 53 00:02:00,080 --> 00:02:02,200 应该可以并发进行的 54 00:02:02,240 --> 00:02:03,600 但实际上在这儿呢这件事情 55 00:02:03,640 --> 00:02:05,040 做起来就比较困难了 56 00:02:05,080 --> 00:02:07,000 如果说我在负载比较重的时候 57 00:02:07,040 --> 00:02:10,040 或者说我的处理能力比较弱的时候 58 00:02:10,080 --> 00:02:10,560 那这时候呢 59 00:02:10,600 --> 00:02:13,640 播放声音的连贯性就会受到影响 60 00:02:13,680 --> 00:02:15,760 然后它资源的利用效率呢 61 00:02:15,800 --> 00:02:16,680 也会比较低 62 00:02:16,720 --> 00:02:17,480 好 因为这样的话 63 00:02:17,520 --> 00:02:19,280 我就没有办法干别的事情了 64 00:02:19,320 --> 00:02:20,960 因为要不然的话稍微慢一点 65 00:02:21,000 --> 00:02:22,880 好 最后我播出来的声音 66 00:02:22,920 --> 00:02:24,840 也就是说在声音上一次给的 67 00:02:24,880 --> 00:02:26,760 数据缓冲没播完之前 68 00:02:26,800 --> 00:02:29,160 如果说你下一波数据没过来的话 69 00:02:29,200 --> 00:02:31,840 那这地方声音它就会不连贯 70 00:02:31,880 --> 00:02:33,840 那说这样播不好 71 00:02:33,880 --> 00:02:35,680 那我们是不是可以把这个程序改成 72 00:02:35,720 --> 00:02:37,600 由多个进程来一块写呢 73 00:02:37,640 --> 00:02:38,920 好 那这时候说我把它改成 74 00:02:38,960 --> 00:02:41,080 三个进程来实现 75 00:02:41,120 --> 00:02:42,040 第一个进程是 76 00:02:42,080 --> 00:02:43,640 管读数据读到内存里头 77 00:02:43,680 --> 00:02:46,520 第二个进程呢是管解压缩 78 00:02:46,560 --> 00:02:47,960 第三个进程管播放 79 00:02:48,000 --> 00:02:50,480 那第一个读完数据的时候给第二个 80 00:02:50,520 --> 00:02:52,320 第二个解压的过程中 81 00:02:52,360 --> 00:02:54,960 由于操作系统的并发性 82 00:02:55,000 --> 00:02:56,160 我可以切换运行 83 00:02:56,200 --> 00:02:58,400 好 那这几个呢就可以 84 00:02:58,440 --> 00:03:00,200 在你读数据的等待阶段 85 00:03:00,240 --> 00:03:01,520 我就可以进行解压了 86 00:03:01,560 --> 00:03:02,480 好 这样的话说起来 87 00:03:02,520 --> 00:03:03,880 它们实际上可以并行 88 00:03:03,920 --> 00:03:05,000 但这时候呢 89 00:03:05,040 --> 00:03:06,520 又有一个问题说 90 00:03:06,560 --> 00:03:07,440 我在这个地方 91 00:03:07,480 --> 00:03:09,880 在做这件事情的时候 92 00:03:09,920 --> 00:03:12,160 它们之间如何来通讯 93 00:03:12,200 --> 00:03:13,880 如何来共享数据 94 00:03:13,920 --> 00:03:16,120 那我们在前面大家还记得 95 00:03:16,160 --> 00:03:18,040 我们在讨论进程的时候 96 00:03:18,080 --> 00:03:20,080 我们讨论进程控制块 97 00:03:20,120 --> 00:03:21,960 主要的一个目的是说让 98 00:03:22,000 --> 00:03:25,160 各个进程之间能很好进行隔离 99 00:03:25,200 --> 00:03:27,720 而现在呢我们这几个隔离 100 00:03:27,760 --> 00:03:29,120 不是它最主要的要求 101 00:03:29,160 --> 00:03:30,200 它们需要的要求是 102 00:03:30,240 --> 00:03:32,600 它们之间能更好共享数据 103 00:03:32,640 --> 00:03:35,120 而这个要求和我们最开始设计进程 104 00:03:35,160 --> 00:03:36,200 多进程的时候 105 00:03:36,240 --> 00:03:39,240 它的目标呢是有一定矛盾的 106 00:03:39,280 --> 00:03:40,840 好 那在这种情况下 107 00:03:40,880 --> 00:03:43,880 我们 它的开销也是相对较大的 108 00:03:43,920 --> 00:03:46,440 因为两个进程之间进行通讯 109 00:03:46,480 --> 00:03:47,400 通常情况下都通过 110 00:03:47,440 --> 00:03:50,440 系统调用要从内核里绕一圈 111 00:03:50,480 --> 00:03:52,880 那如果说这些都是在一个进程内部 112 00:03:52,920 --> 00:03:55,080 那这件事情就会好很多 113 00:03:55,120 --> 00:03:56,840 正是由于这种缘故 114 00:03:56,880 --> 00:03:58,520 我们希望在这里呢 115 00:03:58,560 --> 00:04:01,280 得到这样一种对进程进行改进 116 00:04:01,320 --> 00:04:03,920 在进程内部增加一类实体 117 00:04:03,960 --> 00:04:05,440 使得这一类实体呢 118 00:04:05,480 --> 00:04:08,640 在一个进程内部呢它可以并发执行 119 00:04:08,680 --> 00:04:11,040 有多个指令指针在执行 120 00:04:11,080 --> 00:04:14,080 同时呢它们之间共享的相同地址空间 121 00:04:14,120 --> 00:04:15,600 这样呢它们的信息交流呢 122 00:04:15,640 --> 00:04:17,720 会比原来更方便 123 00:04:17,760 --> 00:04:19,360 因为这时候隔离 124 00:04:19,400 --> 00:04:21,360 不是它们之间要解决的问题 125 00:04:21,400 --> 00:04:24,880 因为它是密切相关的一组执行流 126 00:04:24,920 --> 00:04:27,040 好 而正是由于这种需求 127 00:04:27,080 --> 00:04:30,560 就导致了我们线程的引入 128 00:04:30,600 --> 00:04:33,880 好 那这种思路目标我已经有了 129 00:04:33,920 --> 00:04:36,200 那我怎么来做呢 130 00:04:36,240 --> 00:04:38,520 这就是我们这里说的线程的概念 131 00:04:38,560 --> 00:04:41,400 线程是进程的一部分 132 00:04:41,440 --> 00:04:44,680 它描述指令执行流的状态 133 00:04:44,720 --> 00:04:48,200 好 那它在这里头我把进程当中的 134 00:04:48,240 --> 00:04:50,800 关于执行流的信息呢剥离出来 135 00:04:50,840 --> 00:04:52,080 构成我的线程 136 00:04:52,120 --> 00:04:54,000 但它仍然是进程的一部分 137 00:04:54,040 --> 00:04:55,720 这种剥离有什么样的好处呢 138 00:04:55,760 --> 00:04:57,400 剥离它就可以为并发 139 00:04:57,440 --> 00:04:58,520 在一个进程里头 140 00:04:58,560 --> 00:05:00,720 有多个线程啊提供可能 141 00:05:00,760 --> 00:05:03,480 好 那这样的话把指令执行流的 142 00:05:03,520 --> 00:05:05,960 最小单位变成是线程 143 00:05:06,000 --> 00:05:08,960 然后CPU调度呢变成是线程 144 00:05:09,000 --> 00:05:10,360 好 有了这两条之后 145 00:05:10,400 --> 00:05:12,280 那我在进程内部的并发呢 146 00:05:12,320 --> 00:05:13,600 就变为可能了 147 00:05:13,640 --> 00:05:15,240 好 有了这种变化之后 148 00:05:15,280 --> 00:05:17,000 我们原来的进程控制块 149 00:05:17,040 --> 00:05:18,080 会是啥变化呢 150 00:05:18,120 --> 00:05:20,920 好 原来的进程呢 151 00:05:20,960 --> 00:05:23,680 变成是资源分配的角色 152 00:05:23,720 --> 00:05:25,720 那这是我们的地址空间 153 00:05:25,760 --> 00:05:27,240 我们大家可以看到的 154 00:05:27,280 --> 00:05:29,600 在这里头跟我们原来比的话 155 00:05:29,640 --> 00:05:32,720 跟指令流相关东西就不放在进程里头了 156 00:05:32,760 --> 00:05:34,480 那这里头跟它相关什么 157 00:05:34,520 --> 00:05:35,280 就是堆栈 158 00:05:35,320 --> 00:05:37,600 每个指令流它有函数调用的时候 159 00:05:37,640 --> 00:05:39,960 它必须有自己独立的堆栈 160 00:05:40,000 --> 00:05:41,360 好 那这样我把它剥离出来 161 00:05:41,400 --> 00:05:43,920 变成是我们这里的线程的组成部分 162 00:05:43,960 --> 00:05:47,720 那线程呢是来负责处理机调度的对象 163 00:05:47,760 --> 00:05:49,760 好 那么在这儿呢 我有若干个线程 164 00:05:49,800 --> 00:05:51,960 我在这里有各自线程 有自己堆栈 165 00:05:52,000 --> 00:05:55,480 好 那把相关的关于执行流的状态 166 00:05:55,520 --> 00:05:58,160 的信息呢变成是线程控制块 167 00:05:58,200 --> 00:05:59,800 好 那这个线程控制块呢 168 00:05:59,840 --> 00:06:02,000 也从属于我们的进程控制块 169 00:06:02,040 --> 00:06:03,480 用指针指向它 170 00:06:03,520 --> 00:06:06,160 好 那这时候我就可以有多个指令指针 171 00:06:06,200 --> 00:06:07,120 多个堆栈 172 00:06:07,160 --> 00:06:13,760 和多个CPU里的寄存器的现场保护 173 00:06:13,800 --> 00:06:16,320 因为这个现场保护是和执行流相关的 174 00:06:16,360 --> 00:06:18,200 好 有了这样一个概念之后呢 175 00:06:18,240 --> 00:06:20,280 我们就可以在一个进程内部呢 176 00:06:20,320 --> 00:06:23,040 提高它的并发程度 177 00:06:23,080 --> 00:06:24,520 这个道理说完之后呢 178 00:06:24,560 --> 00:06:26,360 它大致想起来是可以的 179 00:06:26,400 --> 00:06:28,440 那这时候我们会做一些什么样的变化 180 00:06:28,480 --> 00:06:33,400 好 这是我们原来描述的进程的信息 181 00:06:33,440 --> 00:06:36,920 有代码数据 文件 寄存器 堆栈 182 00:06:36,960 --> 00:06:39,000 这是我们原来有的 183 00:06:39,040 --> 00:06:41,560 那在原来里头我只有一个指令指针 184 00:06:41,600 --> 00:06:43,280 所以这部分只有一份 185 00:06:43,320 --> 00:06:45,720 我改完之后变成什么样子呢 186 00:06:45,760 --> 00:06:49,200 这是多线程的进程 那在这里头呢 187 00:06:49,240 --> 00:06:50,840 代码数据打开文件 188 00:06:50,880 --> 00:06:53,200 仍然是和进程属性相关的 189 00:06:53,240 --> 00:06:55,840 它是进程的属性 190 00:06:55,880 --> 00:06:57,880 而跟执行流相关的 191 00:06:57,920 --> 00:06:58,760 我可以变成多份 192 00:06:58,800 --> 00:07:02,040 这时候呢寄存器堆栈 193 00:07:02,080 --> 00:07:04,440 变成是我们线程的属性 194 00:07:04,480 --> 00:07:06,520 线程是进程里的一部分 195 00:07:06,560 --> 00:07:08,440 这时候这样做变化之后 196 00:07:08,480 --> 00:07:12,200 我就可以有多个线程在一个进程内存在了 197 00:07:12,240 --> 00:07:13,960 好 那有了这样做之后呢 198 00:07:14,000 --> 00:07:16,840 我们从道理上来讲我们多线程就可以 199 00:07:16,880 --> 00:07:20,720 很好的支持进程内部的并发 200 00:07:20,760 --> 00:07:24,960 好 这是我们说线程是进程减去资源共享 201 00:07:25,000 --> 00:07:27,640 剩下部分那就是我们执行流的信息 202 00:07:27,680 --> 00:07:28,440 好 那这样的话 203 00:07:28,480 --> 00:07:29,280 我们这样做完之后 204 00:07:29,320 --> 00:07:31,400 线程的引入有什么样好处呢 205 00:07:31,440 --> 00:07:33,400 一个进程内有多个线程 206 00:07:33,440 --> 00:07:36,240 线程之间呢可以并发执行 207 00:07:36,280 --> 00:07:37,120 线程之间呢 208 00:07:37,160 --> 00:07:39,720 可以共享地址空间和文件等资源 209 00:07:39,760 --> 00:07:41,400 这样共享会变得方便 210 00:07:41,440 --> 00:07:43,040 并发性会变得好 211 00:07:43,080 --> 00:07:45,480 那它有啥麻烦呢 212 00:07:45,520 --> 00:07:49,240 因为你在一个进程内部的多个指令流 213 00:07:49,280 --> 00:07:51,840 那这时候呢它们之间的隔离就没有了 214 00:07:51,880 --> 00:07:55,240 好 如果说一个线程行为有异常 215 00:07:55,280 --> 00:07:57,640 它改了另一个线程的相关信息 216 00:07:57,680 --> 00:08:00,600 那么这时候你的整个进程地址空间里的 217 00:08:00,640 --> 00:08:03,280 这些线程就都运行不了了 218 00:08:03,320 --> 00:08:06,280 好 这是呢但是说这种缺点呢是说 219 00:08:06,320 --> 00:08:08,480 我们不是重点关注的 220 00:08:08,520 --> 00:08:10,640 并且我认为各个线程之间 221 00:08:10,680 --> 00:08:11,800 是相互合作的 222 00:08:11,840 --> 00:08:13,080 所以它隔离的成分 223 00:08:13,120 --> 00:08:16,480 我们不要求那么长 224 00:08:16,520 --> 00:08:18,600 好 那有了这样之后我们来说 225 00:08:18,640 --> 00:08:21,160 现在我们在历史上这个变化的过程 226 00:08:21,200 --> 00:08:23,480 这个多线程思路是很好的 227 00:08:23,520 --> 00:08:25,240 那我们看一下这个思路 228 00:08:25,280 --> 00:08:26,560 它在历史上出来的时候 229 00:08:26,600 --> 00:08:28,240 它会是怎样一个变化的过程 230 00:08:28,280 --> 00:08:29,600 也就是说我们现在这些系统里 231 00:08:29,640 --> 00:08:33,760 是如何逐步来支持这个多线程的 232 00:08:33,800 --> 00:08:35,440 最早的计算机系统呢 233 00:08:35,480 --> 00:08:36,920 里头只有一个物理的 234 00:08:36,960 --> 00:08:38,680 指令指针寄存器 235 00:08:38,720 --> 00:08:42,720 那这就是我们最早的单进程系统 236 00:08:42,760 --> 00:08:45,000 比如说像我们的MS-DOS整个系统里 237 00:08:45,040 --> 00:08:47,400 只有一个指令指针流在跑 238 00:08:47,440 --> 00:08:48,400 也就相当于这时候 239 00:08:48,440 --> 00:08:50,720 我们关于进程管理这些机制呢 240 00:08:50,760 --> 00:08:51,760 这里头都没有 241 00:08:51,800 --> 00:08:54,400 好 然后我们说希望提高它的并发性 242 00:08:54,440 --> 00:08:57,320 好 这时候加了多进程系统 243 00:08:57,360 --> 00:08:59,600 那这时候呢我们传统的UNIX系统 244 00:08:59,640 --> 00:09:01,160 就是从这么做起来的 245 00:09:01,200 --> 00:09:02,760 这时候我们在进程切换 246 00:09:02,800 --> 00:09:04,920 和进程之间的资源隔离 247 00:09:04,960 --> 00:09:07,360 那都是在这个阶段给出来的 248 00:09:07,400 --> 00:09:08,880 那有了这个阶段之后 249 00:09:08,920 --> 00:09:10,640 我们想进一步提高 250 00:09:10,680 --> 00:09:13,360 这个一个进程内部的并发性 251 00:09:13,400 --> 00:09:18,080 就变成了我们现在的多线程系统 252 00:09:18,120 --> 00:09:19,360 那在一个进程 253 00:09:19,400 --> 00:09:22,000 同时有多线程和多进程 254 00:09:22,040 --> 00:09:23,320 那就是我们现在的 255 00:09:23,360 --> 00:09:26,000 这种系统里呢支持的情况 256 00:09:26,040 --> 00:09:28,400 实际上在这里头我们还有一类系统 257 00:09:28,440 --> 00:09:30,360 在现实的生活当中也是存在的 258 00:09:30,400 --> 00:09:32,840 这就是单进程多线程系统 259 00:09:32,880 --> 00:09:34,400 那这一些系统呢 260 00:09:34,440 --> 00:09:35,920 通常情况下是对于 261 00:09:35,960 --> 00:09:39,400 那些对并发执行要求高 262 00:09:39,440 --> 00:09:41,840 对信息共享要求高的 263 00:09:41,880 --> 00:09:43,360 但是对安全隔离 264 00:09:43,400 --> 00:09:44,840 要求低的这些系统里头 265 00:09:44,880 --> 00:09:46,680 比如说像我们的路由器里头 266 00:09:46,720 --> 00:09:47,920 路由器里头呢 267 00:09:47,960 --> 00:09:50,040 它是负责分组的转发 268 00:09:50,080 --> 00:09:51,080 路由表的查询 269 00:09:51,120 --> 00:09:52,640 这些是密切相关的 270 00:09:52,680 --> 00:09:54,520 但是它们之间呢 271 00:09:54,560 --> 00:09:56,920 需要很好的这个信息共享 272 00:09:56,960 --> 00:09:59,520 但是由于他们都是一家做的 273 00:09:59,560 --> 00:10:01,600 并且路由器里呢不支持 274 00:10:01,640 --> 00:10:04,200 你第三方往顶上加自己的程序 275 00:10:04,240 --> 00:10:05,640 好 那这时候呢它的隔离 276 00:10:05,680 --> 00:10:06,520 就做的比较弱 277 00:10:06,560 --> 00:10:08,600 好 那这样的话不做隔离的结果就是 278 00:10:08,640 --> 00:10:10,600 我这里只支持一个进程里头 279 00:10:10,640 --> 00:10:11,880 有很多的线程 280 00:10:11,920 --> 00:10:15,040 比如说像我们用到的PSOS操作系统 281 00:10:15,080 --> 00:10:17,960 它在路由器上用的它就有这种特征 282 00:10:18,000 --> 00:10:21,720 好 那有了这个之后 那我们来看 283 00:10:21,760 --> 00:10:22,840 进程和线程 284 00:10:22,880 --> 00:10:24,680 它们实际上什么样的关系呢 285 00:10:24,720 --> 00:10:26,720 进程是资源分配的单位 286 00:10:26,760 --> 00:10:29,160 线程是处理机调度的单位 287 00:10:29,200 --> 00:10:31,480 好 进程和线程呢 288 00:10:31,520 --> 00:10:33,680 一个是拥有完整的资源 289 00:10:33,720 --> 00:10:38,840 一个是只拥有跟执行流相关的资源 290 00:10:38,880 --> 00:10:40,720 那这样一来的话我们线程呢 291 00:10:40,760 --> 00:10:42,680 它所要保存信息就少了 292 00:10:42,720 --> 00:10:44,320 那在同一个进程里头 293 00:10:44,360 --> 00:10:46,240 它们相互之间切换的时候 294 00:10:46,280 --> 00:10:48,440 你需要保存的信息就少了 295 00:10:48,480 --> 00:10:50,200 这个时候它的速度就会快 296 00:10:50,240 --> 00:10:54,800 好 每一个原来说跟执行相关的 297 00:10:54,840 --> 00:10:56,120 这些进程状态 298 00:10:56,160 --> 00:10:58,400 现在都转成是线程的状态了 299 00:10:58,440 --> 00:11:02,600 所以线程有就绪 等待 执行 运行 300 00:11:02,640 --> 00:11:03,720 几种基本的状态 301 00:11:03,760 --> 00:11:06,680 它们之间的状态的转换 302 00:11:06,720 --> 00:11:09,800 跟我们前面讲的进程呢是完全一致的 303 00:11:09,840 --> 00:11:11,120 好 有了这些之后 304 00:11:11,160 --> 00:11:12,760 那我们的线程呢 305 00:11:12,800 --> 00:11:14,880 就会有很好的特征 306 00:11:14,920 --> 00:11:16,160 那这时候它减少 307 00:11:16,200 --> 00:11:19,600 并发执行的时间和空间开销 308 00:11:19,640 --> 00:11:23,640 时间开销呢是指说创建终止切换 309 00:11:23,680 --> 00:11:25,960 它的时间都会比原来少 310 00:11:26,000 --> 00:11:29,480 这里所说的创建终止切换 311 00:11:29,520 --> 00:11:33,360 是指在一个进程内部的线程的创建 312 00:11:33,400 --> 00:11:34,800 如果说你创建一个 313 00:11:34,840 --> 00:11:36,880 新的进程里的新线程 314 00:11:36,920 --> 00:11:38,960 那和原来的进程创建呢 315 00:11:39,000 --> 00:11:40,160 开销是相当的 316 00:11:40,200 --> 00:11:42,280 甚至于有可能会多一点 317 00:11:42,320 --> 00:11:44,000 好 然后说我在这里头呢 318 00:11:44,040 --> 00:11:45,320 它们之间的共享呢 319 00:11:45,360 --> 00:11:47,440 会比原来更方便 320 00:11:47,480 --> 00:11:48,960 好 那到这个地方呢 321 00:11:49,000 --> 00:11:53,400 我们就说清楚了线程的基本概念 322 00:11:53,440 --> 00:11:55,720 那下面我们会去说如何来实现它 323 00:11:55,760 --> 00:11:56,000 324 00:11:56,040 --> 00:11:56,040