Ubuntu中open-file-description table与Tanenbaum描述不符?Shell脚本文件写入测试问题求助
问题核心:混淆了「独立进程打开文件」和「共享打开文件描述符」的场景
这是个非常典型的场景误解——你测试的脚本和Tanenbaum在《现代操作系统》里描述的根本不是同一个文件操作场景,Ubuntu(基于Linux内核)的实现完全符合书中的理论,只是你的脚本没有触发「共享打开文件描述符(OFD)」的条件。
先明确书中的场景到底是什么
Tanenbaum提到的“p1和p2使用同一个open-file-description table”,指的是两个进程共享同一个内核级别的打开文件描述(OFD)——这种情况只会发生在:
- 一个进程打开文件后,通过
fork()创建子进程,子进程会继承父进程的文件描述符,此时父子进程的文件描述符指向同一个OFD; - 同一进程内通过
dup()/dup2()复制文件描述符,或者用特定打开标志复用已有的OFD。
在这种共享OFD的场景下,OFD中记录的文件偏移量是全局共享的——p1写入后移动了偏移量,p2会接着这个位置继续写入,不会覆盖之前的内容。
你的脚本为什么会覆盖?
你写的脚本里,echo 11 > a.txt和echo 12 > a.txt是两个完全独立的进程:
- 第一个
echo进程启动时,shell会帮它执行open("a.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666)——这里的O_TRUNC标志会直接把文件长度截断为0,然后写入"11\n",接着关闭文件; - 第二个
echo进程启动时,同样会执行带O_TRUNC的打开操作,再次清空文件,写入"12\n"后关闭。
本质上是两个进程分别打开、截断、写入、关闭文件,完全没有共享任何OFD,自然会出现覆盖的结果。
如何验证书中的描述?
我们可以写一个真正触发共享OFD的脚本,比如让两个子进程继承父进程打开的文件描述符:
#!/bin/bash # 打开a.txt,分配文件描述符3,使用读写模式且不截断文件(如果文件存在则保留内容) exec 3<> a.txt # 启动两个子进程,它们会继承文件描述符3,共享同一个OFD (echo "来自p1的内容" >&3) & (echo "来自p2的内容" >&3) & # 等待两个子进程执行完成 wait # 关闭文件描述符3 exec 3>&-
运行这个脚本后,打开a.txt会看到两个进程的内容都被写入(顺序可能因为进程调度略有不同,但绝对不会互相覆盖)——这就是Tanenbaum书中描述的场景。
总结
Linux内核(包括Ubuntu)的文件系统实现完全符合POSIX标准,也和Tanenbaum的理论一致。你的测试脚本只是没有命中「共享OFD」的场景,才会出现和预期不符的结果。
内容的提问来源于stack exchange,提问作者Phi Quang Phuoc
相关产品推荐
相关产品推荐

