0 00:00:00,000 --> 00:00:07,440 1 00:00:07,480 --> 00:00:09,040 下面我们来讨论 2 00:00:09,080 --> 00:00:12,160 文件描述符这个基本的概念 3 00:00:12,200 --> 00:00:16,920 文件描述符是指打开的文件 4 00:00:16,960 --> 00:00:20,800 它在内存当中所维护的相关信息 5 00:00:20,840 --> 00:00:25,720 首先我们来讨论一下打开文件的过程 6 00:00:25,760 --> 00:00:27,200 我在读写数据之前 7 00:00:27,240 --> 00:00:29,000 我必须打开文件 8 00:00:29,040 --> 00:00:31,040 这是我们通常情况下 9 00:00:31,080 --> 00:00:34,880 你写的程序里头的文件访问的模式 10 00:00:34,920 --> 00:00:37,480 打开然后进行读 或者写操作 11 00:00:37,520 --> 00:00:39,240 完成之后 一个关闭 12 00:00:39,280 --> 00:00:41,200 我就不再对这个文件进行操作了 13 00:00:41,240 --> 00:00:43,000 针对于这种模式呢 14 00:00:43,040 --> 00:00:45,000 在操作系统内核当中 15 00:00:45,040 --> 00:00:48,400 维护了打开文件的相关信息 16 00:00:48,440 --> 00:00:51,800 也就是说它会跟踪进程打开的文件 17 00:00:51,840 --> 00:00:53,920 所谓的跟踪就是在内核当中 18 00:00:53,960 --> 00:00:56,280 维护了一个打开文件表 19 00:00:56,320 --> 00:00:58,080 这个文件表里的每一项 20 00:00:58,120 --> 00:01:00,680 对应一个打开的文件 21 00:01:00,720 --> 00:01:02,520 这时候我给它一个标识 22 00:01:02,560 --> 00:01:04,200 就是文件描述符 23 00:01:04,240 --> 00:01:05,680 也就是说文件描述符 24 00:01:05,720 --> 00:01:08,000 是打开文件的一个标识 25 00:01:08,040 --> 00:01:11,880 为什么我不直接用文件的标识呢 26 00:01:11,920 --> 00:01:14,120 原因在于打开文件的数目和 27 00:01:14,160 --> 00:01:16,800 你的文件系统里的文件数目 28 00:01:16,840 --> 00:01:18,680 是有数量级的差别的 29 00:01:18,720 --> 00:01:19,480 这样的话我可以给它一个 30 00:01:19,520 --> 00:01:23,520 更简单的标识来方便我们的访问 31 00:01:23,560 --> 00:01:26,080 文件描述符是操作系统 32 00:01:26,120 --> 00:01:29,720 在打开文件表中维护的 33 00:01:29,760 --> 00:01:32,760 打开文件的状态和信息 34 00:01:32,800 --> 00:01:34,360 这里有些什么样的信息呢 35 00:01:34,400 --> 00:01:37,560 首先第一个是文件指针 36 00:01:37,600 --> 00:01:39,600 我们在读写文件的时候 37 00:01:39,640 --> 00:01:43,000 最后一次读写的位置 38 00:01:43,040 --> 00:01:46,600 每个进程都维护自己的打开文件指针 39 00:01:46,640 --> 00:01:48,480 也就相当于我有一个文件 40 00:01:48,520 --> 00:01:50,640 有多个进程对它进行读写 41 00:01:50,680 --> 00:01:53,120 在读的时候你的这个指针 42 00:01:53,160 --> 00:01:57,080 每个进程只是跟自己的指针相关联 43 00:01:57,120 --> 00:01:59,720 另外的一个进程读写相同的文件 44 00:01:59,760 --> 00:02:01,720 这时候你的文件指针 45 00:02:01,760 --> 00:02:04,280 并不随着它的读写而发生改变 46 00:02:04,320 --> 00:02:05,920 这就是我们这里说的 47 00:02:05,960 --> 00:02:10,440 每个进程分别维护自己的打开文件指针 48 00:02:10,480 --> 00:02:12,200 除了文件指针之外 49 00:02:12,240 --> 00:02:15,360 再有一个是文件打开计数 50 00:02:15,400 --> 00:02:17,400 这里指的是当前这个 51 00:02:17,440 --> 00:02:19,840 被打开的文件打开的次数 52 00:02:19,880 --> 00:02:21,960 记录这个次数的意思是在于 53 00:02:22,000 --> 00:02:24,360 最后一个进程关闭文件的时候 54 00:02:24,400 --> 00:02:26,000 那么就可以将这个文件 55 00:02:26,040 --> 00:02:29,880 从打开文件表当中去除了 56 00:02:29,920 --> 00:02:32,920 这是打开文件计数 57 00:02:32,960 --> 00:02:36,960 同时还有就是文件在磁盘上的位置 58 00:02:37,000 --> 00:02:38,480 这时候我们会把一部分 59 00:02:38,520 --> 00:02:42,280 磁盘上的文件的内容缓存到内存当中 60 00:02:42,320 --> 00:02:42,840 所以这时候 61 00:02:42,880 --> 00:02:45,200 我要记录文件在磁盘上的位置 62 00:02:45,240 --> 00:02:46,680 你下次再读的时候 63 00:02:46,720 --> 00:02:48,240 有缓存的这些内容 64 00:02:48,280 --> 00:02:50,320 我就可以利用内存当中 65 00:02:50,360 --> 00:02:52,320 缓存的数据让你进行访问 66 00:02:52,360 --> 00:02:52,960 67 00:02:53,000 --> 00:02:55,160 再有是访问权限 68 00:02:55,200 --> 00:02:57,720 每个进程访问文件的时候 69 00:02:57,760 --> 00:03:00,480 它是以什么样的方式来进行访问 70 00:03:00,520 --> 00:03:03,200 你比如说只读 可读可写 71 00:03:03,240 --> 00:03:05,360 为了能够通过文件系统 72 00:03:05,400 --> 00:03:08,440 来实现对文件的访问 73 00:03:08,480 --> 00:03:10,120 我们有必要来讨论一下 74 00:03:10,160 --> 00:03:13,560 文件从用户和系统的角度来讲 75 00:03:13,600 --> 00:03:15,080 它是个什么样的 76 00:03:15,120 --> 00:03:16,720 这就是我们这里说到的 77 00:03:16,760 --> 00:03:19,840 文件的用户视图和系统视图 78 00:03:19,880 --> 00:03:21,880 用户视图是指 79 00:03:21,920 --> 00:03:25,520 我们用户进程看到的文件是什么样 80 00:03:25,560 --> 00:03:28,640 这里头呢 文件是持久的数据结构 81 00:03:28,680 --> 00:03:29,760 这是你应用进程 82 00:03:29,800 --> 00:03:31,960 我需要读写文件里的数据的时候 83 00:03:32,000 --> 00:03:34,040 这些数据是有结构的 84 00:03:34,080 --> 00:03:37,160 这是我们这里想看到的 85 00:03:37,200 --> 00:03:39,200 但是从系统的角度来讲 86 00:03:39,240 --> 00:03:40,640 它并不关心这个事 87 00:03:40,680 --> 00:03:44,520 所以系统提供了一个文件的访问接口 88 00:03:44,560 --> 00:03:45,400 在这里头呢 89 00:03:45,440 --> 00:03:48,200 文件变成了一个字节序列了 90 00:03:48,240 --> 00:03:49,800 当然对这一点的理解 91 00:03:49,840 --> 00:03:53,120 不同的系统会有一些差别 92 00:03:53,160 --> 00:03:55,760 在Unix 系统Linux系统 这一类的系统里 93 00:03:55,800 --> 00:03:59,160 它认为文件内容是字节的序列 94 00:03:59,200 --> 00:04:00,960 操作系统并不关心 95 00:04:01,000 --> 00:04:04,000 存储在磁盘上的数据这些数据的格式 96 00:04:04,040 --> 00:04:06,080 这是你应用进程需要关心的 97 00:04:06,120 --> 00:04:09,040 这就是我们这里的系统视图 98 00:04:09,080 --> 00:04:11,000 也就是说它把文件 99 00:04:11,040 --> 00:04:14,080 视为是数据块的集合 100 00:04:14,120 --> 00:04:16,840 说到数据块呢 这有两个 101 00:04:16,880 --> 00:04:19,920 我们访问的数据块和磁盘的扇区 102 00:04:19,960 --> 00:04:21,840 有关系但是也有区别 103 00:04:21,880 --> 00:04:24,720 数据块是逻辑的存储单位 104 00:04:24,760 --> 00:04:27,040 可能由多个扇区组成 105 00:04:27,080 --> 00:04:30,080 而扇区是物理的存储单元 106 00:04:30,120 --> 00:04:32,200 数据块的大小和扇区的大小 107 00:04:32,240 --> 00:04:34,200 可能不一样 108 00:04:34,240 --> 00:04:35,440 通常情况下是 109 00:04:35,480 --> 00:04:38,160 几个扇区构成一个数据块 110 00:04:38,200 --> 00:04:39,360 特别是对于容量比较大的 111 00:04:39,400 --> 00:04:42,800 这些磁盘来说是这样的 112 00:04:42,840 --> 00:04:46,200 有了用户的视角和系统的视角 113 00:04:46,240 --> 00:04:48,520 那这时候它们之间的转换怎么来做呢 114 00:04:48,560 --> 00:04:52,000 我们先来看一个文件读写的例子 115 00:04:52,040 --> 00:04:53,560 进程读文件的时候 116 00:04:53,600 --> 00:04:54,920 它是怎么在做呢 117 00:04:54,960 --> 00:04:58,000 首先读取你对应的这个内容 118 00:04:58,040 --> 00:04:59,680 所在的那个数据块 119 00:04:59,720 --> 00:05:03,240 整块读出来 也就是说磁盘的访问 120 00:05:03,280 --> 00:05:04,400 它具有这样一个特征 121 00:05:04,440 --> 00:05:06,640 它的最小访问单位只能是块 122 00:05:06,680 --> 00:05:10,360 我不能去对块当中的单独的字节 123 00:05:10,400 --> 00:05:12,360 进行读或者是写 124 00:05:12,400 --> 00:05:14,320 也就是说你想读出一个字节 125 00:05:14,360 --> 00:05:15,560 也必须把整块读出来 126 00:05:15,600 --> 00:05:16,880 你想写一个字节 127 00:05:16,920 --> 00:05:18,920 也必须把整块重新写 128 00:05:18,960 --> 00:05:19,760 那这样一来的话 129 00:05:19,800 --> 00:05:20,560 我在这个地方就是 130 00:05:20,600 --> 00:05:22,760 读出字节所在的数据块 131 00:05:22,800 --> 00:05:27,080 然后把其中需要的内容返回给进程 132 00:05:27,120 --> 00:05:28,880 这是你的读操作 133 00:05:28,920 --> 00:05:31,520 而进程的写文件操作呢 134 00:05:31,560 --> 00:05:35,240 它是先读取相应的数据块 135 00:05:35,280 --> 00:05:37,760 也就是说你要写的那个位置所对应的 136 00:05:37,800 --> 00:05:39,840 那一块的内容全部读出来 137 00:05:39,880 --> 00:05:44,360 然后修改相应块当中的对应的内容 138 00:05:44,400 --> 00:05:47,560 修改完毕之后 把整块写回去 139 00:05:47,600 --> 00:05:50,320 这是你的写操作 对于这种情况呢 140 00:05:50,360 --> 00:05:55,240 我们在这里头从用户视图到系统视图 141 00:05:55,280 --> 00:05:56,440 就有一个转换 142 00:05:56,480 --> 00:05:58,040 这个转换过程当中的 143 00:05:58,080 --> 00:06:03,160 一个重要的特征是文件系统当中的操作 144 00:06:03,200 --> 00:06:06,320 它的基本操作单位是数据块 145 00:06:06,360 --> 00:06:07,760 有了这个之后 146 00:06:07,800 --> 00:06:09,880 我们在这里就会有这样一个特征 147 00:06:09,920 --> 00:06:11,760 你即使只读一个字节 148 00:06:11,800 --> 00:06:13,360 也需要把整块读出来 149 00:06:13,400 --> 00:06:14,840 你比如说我这里一个字节 150 00:06:14,880 --> 00:06:17,800 而一块呢 是4K 那这时候呢 151 00:06:17,840 --> 00:06:18,840 也就相当于我为了 152 00:06:18,880 --> 00:06:21,400 读其中千分之零点几的数据 153 00:06:21,440 --> 00:06:24,360 读写的量实际上是它的上千倍 154 00:06:24,400 --> 00:06:25,320 所以在这里头呢 155 00:06:25,360 --> 00:06:27,320 读写数据的时候我们一种优化 156 00:06:27,360 --> 00:06:29,080 就是一块的内容 157 00:06:29,120 --> 00:06:29,920 我是不是有可能 158 00:06:29,960 --> 00:06:32,120 把它充分的利用起来 159 00:06:32,160 --> 00:06:35,120 160 00:06:35,160 --> 00:06:37,560 在具体讨论内容的时候 161 00:06:37,600 --> 00:06:40,000 我们还有一个问题需要在这来讨论 162 00:06:40,040 --> 00:06:44,280 就是进程对文件的访问模式 163 00:06:44,320 --> 00:06:45,120 也就是说操作系统 164 00:06:45,160 --> 00:06:46,840 在实现文件系统的时候 165 00:06:46,880 --> 00:06:48,800 它需要了解用户进程 166 00:06:48,840 --> 00:06:50,720 是如何访问文件的 167 00:06:50,760 --> 00:06:51,600 那么在这里头呢 168 00:06:51,640 --> 00:06:53,520 有这样三种方式 169 00:06:53,560 --> 00:06:56,120 第一种是顺序访问 170 00:06:56,160 --> 00:06:59,680 按文件的字节序列这个顺序 171 00:06:59,720 --> 00:07:02,080 依次进行读写操作 172 00:07:02,120 --> 00:07:04,520 我们现在用到的大多数文件访问 173 00:07:04,560 --> 00:07:08,240 都是顺序访问 174 00:07:08,280 --> 00:07:10,560 而第二种是随机访问 175 00:07:10,600 --> 00:07:12,720 我访问的位置并不是顺序的 176 00:07:12,760 --> 00:07:14,120 从中间读 177 00:07:14,160 --> 00:07:15,080 这种做法呢 178 00:07:15,120 --> 00:07:17,960 在实际的进程访问当中并不常用 179 00:07:18,000 --> 00:07:19,720 但是仍然很重要 180 00:07:19,760 --> 00:07:22,920 比如说像我们在这里的虚拟存储当中 181 00:07:22,960 --> 00:07:26,360 把内存页存储到对换文件当中 182 00:07:26,400 --> 00:07:29,160 这时候它的访问就是随机的 183 00:07:29,200 --> 00:07:32,960 它对系统的性能的影响很大 184 00:07:33,000 --> 00:07:35,320 第三个是索引访问 185 00:07:35,360 --> 00:07:37,000 依据数据特征 186 00:07:37,040 --> 00:07:40,040 来找文件当中的相应位置的数据 187 00:07:40,080 --> 00:07:42,200 这种做法通常情况下 188 00:07:42,240 --> 00:07:43,160 在我们操作系统里 189 00:07:43,200 --> 00:07:46,160 并不完整的提供索引访问机制 190 00:07:46,200 --> 00:07:48,400 一种做法是在上边建数据库 191 00:07:48,440 --> 00:07:53,920 数据库提供完善的索引访问方式 192 00:07:53,960 --> 00:07:55,200 实际上某种角度上来讲 193 00:07:55,240 --> 00:07:57,760 我们可以认为操作系统里的文件系统 194 00:07:57,800 --> 00:08:00,440 是一个小型的数据库 195 00:08:00,480 --> 00:08:04,240 这是索引访问文件的一个示例 196 00:08:04,280 --> 00:08:07,200 说我要想找文件里的某一个记录 197 00:08:07,240 --> 00:08:08,200 这时我怎么找呢 198 00:08:08,240 --> 00:08:09,640 我需要先找着 199 00:08:09,680 --> 00:08:12,040 这个记录对应的位置在哪 200 00:08:12,080 --> 00:08:13,720 这时候形成一个索引 201 00:08:13,760 --> 00:08:15,360 一种我把它整个读出来 202 00:08:15,400 --> 00:08:18,240 然后再挑我想要的这个 203 00:08:18,280 --> 00:08:19,640 这时候它的效率会比较低 204 00:08:19,680 --> 00:08:20,280 所以在这呢 205 00:08:20,320 --> 00:08:21,560 基于索引的访问的话 206 00:08:21,600 --> 00:08:23,840 就是我在这里加了一个索引 207 00:08:23,880 --> 00:08:27,280 事先把相应的内容做了一种抽象 208 00:08:27,320 --> 00:08:28,600 然后这时候我再来访问的时候 209 00:08:28,640 --> 00:08:31,040 我先访问索引文件里的内容 210 00:08:31,080 --> 00:08:32,480 找到它对应的位置 211 00:08:32,520 --> 00:08:35,240 这时候再去读它相应的记录的内容 212 00:08:35,280 --> 00:08:38,000 这样的话就可以提高它的读写效率 213 00:08:38,040 --> 00:08:41,320 这是索引访问的做法 214 00:08:41,360 --> 00:08:43,760 215 00:08:43,800 --> 00:08:45,960 对于文件的内部呢 216 00:08:46,000 --> 00:08:48,440 我们说从操作系统的角度来讲 217 00:08:48,480 --> 00:08:50,240 它并不关心它的结构 218 00:08:50,280 --> 00:08:52,680 在实际的系统当中 219 00:08:52,720 --> 00:08:55,680 我们可以把它视为这样几种结构 220 00:08:55,720 --> 00:08:57,680 一种是无结构的 221 00:08:57,720 --> 00:09:01,360 它就是一个单词 或者说字节的序列 222 00:09:01,400 --> 00:09:04,160 第二种是简单的记录结构 223 00:09:04,200 --> 00:09:06,960 我把它分成若干列 224 00:09:07,000 --> 00:09:09,280 每一列是其中的一个内容 225 00:09:09,320 --> 00:09:12,240 这种列的大小或者记录的大小 226 00:09:12,280 --> 00:09:13,440 可以有固定长度的 227 00:09:13,480 --> 00:09:15,400 也可以是可变长度的 228 00:09:15,440 --> 00:09:17,840 再有一种就是复杂结构的 229 00:09:17,880 --> 00:09:19,600 我在这里定义复杂的结构 230 00:09:19,640 --> 00:09:21,720 通常情况下这些复杂的结构 231 00:09:21,760 --> 00:09:24,440 都是由你应用程序来识别 232 00:09:24,480 --> 00:09:26,280 而从操作系统层面来讲 233 00:09:26,320 --> 00:09:28,240 这些结构并不是很关心 234 00:09:28,280 --> 00:09:30,400 但是为什么我们在这里会来讨论 235 00:09:30,440 --> 00:09:31,280 它的内部结构呢 236 00:09:31,320 --> 00:09:33,440 就是你到底是可执行文件 237 00:09:33,480 --> 00:09:34,880 还是文本文件 238 00:09:34,920 --> 00:09:36,880 在操作系统接口这一层面上 239 00:09:36,920 --> 00:09:40,000 它提供某种程度的支持和识别 240 00:09:40,040 --> 00:09:43,200 241 00:09:43,240 --> 00:09:46,760 接下来是文件的共享和访问控制 242 00:09:46,800 --> 00:09:47,960 多用户系统里头 243 00:09:48,000 --> 00:09:50,440 文件的共享就变得很必要了 244 00:09:50,480 --> 00:09:52,160 你比如说系统里很多文件 245 00:09:52,200 --> 00:09:54,120 你不可以每个用户保存一份 246 00:09:54,160 --> 00:09:56,800 通过共享可以节约磁盘的存储空间 247 00:09:56,840 --> 00:09:59,200 在这里共享之后就带来一个问题 248 00:09:59,240 --> 00:10:01,800 我的访问如何来控制 249 00:10:01,840 --> 00:10:03,800 访问控制是每个用户 250 00:10:03,840 --> 00:10:05,760 它到底可以访问哪些文件 251 00:10:05,800 --> 00:10:07,520 可以以什么样的方式来访问 252 00:10:07,560 --> 00:10:09,080 这是访问权限 253 00:10:09,120 --> 00:10:10,600 在我们现在的系统里 254 00:10:10,640 --> 00:10:13,680 通常情况下的访问权限有这样几种 255 00:10:13,720 --> 00:10:18,600 读 写 执行 删除和看到它的列表 256 00:10:18,640 --> 00:10:20,000 这些基本的权限呢 257 00:10:20,040 --> 00:10:22,400 对应到每一个用户 258 00:10:22,440 --> 00:10:26,040 这就是我们的文件访问控制列表 ACL 259 00:10:26,080 --> 00:10:28,880 对于每一个文件 每一个用户 260 00:10:28,920 --> 00:10:31,560 它有什么样的权限 261 00:10:31,600 --> 00:10:34,760 在Unix系统里它的做法是这样的 262 00:10:34,800 --> 00:10:37,880 用户分成当前的用户 263 00:10:37,920 --> 00:10:40,440 用户所在的组和系统里的所有人 264 00:10:40,480 --> 00:10:42,240 也就是分成三个范围 265 00:10:42,280 --> 00:10:45,560 然后每一个文件的访问权限 266 00:10:45,600 --> 00:10:49,080 分成读 写 执行这样三种权限 267 00:10:49,120 --> 00:10:50,760 如果在这种情况下 268 00:10:50,800 --> 00:10:53,240 你要想把所有的文件权限全部列清楚 269 00:10:53,280 --> 00:10:55,440 这时候就构成一个访问矩阵了 270 00:10:55,480 --> 00:10:57,800 三种类型的用户 271 00:10:57,840 --> 00:11:00,320 然后它有三种权限组合到一起 272 00:11:00,360 --> 00:11:02,840 每一个文件有一个自己的选择 273 00:11:02,880 --> 00:11:05,360 那这样我给出整个系统当中的 274 00:11:05,400 --> 00:11:07,440 每一个文件的访问权限 275 00:11:07,480 --> 00:11:09,360 为了让这件事情做起来方便 276 00:11:09,400 --> 00:11:13,000 我们需要识别用户 277 00:11:13,040 --> 00:11:14,560 我必须识别用户是谁 278 00:11:14,600 --> 00:11:17,920 我才能决定它有什么样的访问权限 279 00:11:17,960 --> 00:11:20,920 然后为了让这件事情做起来效率更高 280 00:11:20,960 --> 00:11:24,360 我们可以把用户分组 提供组标识 281 00:11:24,400 --> 00:11:24,800 那这样的话 282 00:11:24,840 --> 00:11:27,560 我可以给一组人设相同的权限 283 00:11:27,600 --> 00:11:29,160 我只需要判断这个用户 284 00:11:29,200 --> 00:11:30,960 是否在这个组就行了 285 00:11:31,000 --> 00:11:32,280 关于访问权限 286 00:11:32,320 --> 00:11:34,640 我们在这里就只做一个简单讨论 287 00:11:34,680 --> 00:11:37,360 深入的讨论在不同的操作系统当中 288 00:11:37,400 --> 00:11:39,000 都有很多的内容 289 00:11:39,040 --> 00:11:41,720 290 00:11:41,760 --> 00:11:43,440 接下来一个问题是说 291 00:11:43,480 --> 00:11:47,000 共享所导致的语义一致性 292 00:11:47,040 --> 00:11:50,400 当多个进程同时访问共享文件的时候 293 00:11:50,440 --> 00:11:52,240 它们如何来协调 294 00:11:52,280 --> 00:11:53,160 这里的协调 295 00:11:53,200 --> 00:11:56,600 我们同前边的同步算法很相似 296 00:11:56,640 --> 00:11:58,880 我需要协调我写到里头的内容 297 00:11:58,920 --> 00:12:01,320 你读的内容大家是不是一致的 298 00:12:01,360 --> 00:12:04,600 由于磁盘和网络延时的缘故 299 00:12:04,640 --> 00:12:06,000 我们在文件系统里 300 00:12:06,040 --> 00:12:08,640 对这个问题是弱化处理的 301 00:12:08,680 --> 00:12:10,720 也就是说它的设计很简单 302 00:12:10,760 --> 00:12:13,440 在Unix系统里简单到什么程度呢 303 00:12:13,480 --> 00:12:15,800 对于文件的读写 304 00:12:15,840 --> 00:12:18,160 一个用户写进去的内容 305 00:12:18,200 --> 00:12:20,160 其他的用户立即可见 306 00:12:20,200 --> 00:12:21,800 然后共享文件呢 307 00:12:21,840 --> 00:12:25,080 允许多个用户同时读和写 308 00:12:25,120 --> 00:12:26,200 基本上是说在这里 309 00:12:26,240 --> 00:12:29,000 它没有协调的这些控制 310 00:12:29,040 --> 00:12:29,880 这样一来的话 311 00:12:29,920 --> 00:12:31,440 你的内容读写是不是完整 312 00:12:31,480 --> 00:12:35,040 就需要靠应用程序自己来把握 313 00:12:35,080 --> 00:12:37,120 那也就相当于我把这个一致性的问题 314 00:12:37,160 --> 00:12:40,240 甩给应用进程自己去处理了 315 00:12:40,280 --> 00:12:41,360 还有两种做法呢 316 00:12:41,400 --> 00:12:43,840 一个是会话语义 317 00:12:43,880 --> 00:12:47,560 写入的内容只有当文件被关闭的时候 318 00:12:47,600 --> 00:12:49,240 其它用户才可见 这样一来的话 319 00:12:49,280 --> 00:12:51,640 你相当于改的内容必须写完整了 320 00:12:51,680 --> 00:12:53,280 其他的进程才能看得到 321 00:12:53,320 --> 00:12:55,320 这样一来它们之间要协调的事情 322 00:12:55,360 --> 00:12:56,560 就变得会简单一些 323 00:12:56,600 --> 00:12:59,120 但是它的效率会低一些 324 00:12:59,160 --> 00:13:01,840 还有一种是读写锁 325 00:13:01,880 --> 00:13:03,360 操作系统在这里呢 326 00:13:03,400 --> 00:13:07,080 提供几种基本的互斥访问锁 327 00:13:07,120 --> 00:13:09,200 由应用进程自己来选择 328 00:13:09,240 --> 00:13:11,720 我需要什么样的同步互斥 329 00:13:11,760 --> 00:13:14,040 来保证我内容的一致性 330 00:13:14,080 --> 00:13:17,120 这是一致性的问题 331 00:13:17,160 --> 00:13:17,440 332 00:13:17,480 --> 00:13:17,840 333 00:13:17,880 --> 00:13:17,920