主要观点:
- 介绍了三种 Unix 文件锁定 API:flock()、fcntl()、lockf(),它们各有特点和限制。
- 强调不同操作系统和文件系统中文件锁定的复杂性和不可靠性。
- 指出 advisory 锁(如 fcntl 锁)的一些特性和问题,如不跨 fork、锁与文件描述符和 inode 的关系等。
- 提醒不要在同一文件上使用多种类型的锁,以免导致程序在不同系统上失败。
- 不建议使用 mandatory 锁,因其难以控制且可能导致问题。
- 讨论了 Python 中文件锁定的相关情况,fcntl 模块中的不同函数存在问题,建议使用 fcntl.lockf()。
- 作者在编写使用文件锁定的 Python 程序时遇到 MacOS 上 fcntl 锁的问题并提交了 bug。
- 后续更新提到 Linux 新增了 F_OFD_SETLK 锁,Windows 10 WSL 中 fcntl 锁存在问题,MacOS 已修复 fcntl 锁的问题。
关键信息:
- flock() 简单但非 POSIX 标准,不支持 NFS,升级为 exclusive 锁有风险,fork 后行为不确定。
- fcntl() 标准化,功能强大,支持 NFS,但在不同系统和内核中有不同行为,共享锁可原子升级为 exclusive 锁,锁与 (pid,inode) 对相关,有两个奇怪行为。
- lockf() 标准化,API 较简单但无法查询锁的所有者,可能不被 pre-POSIX BSD 系统支持,不建议使用。
- 不同锁类型在同一文件上的交互基本未定义,应明确使用的锁类型。
- Python 中 fcntl 模块的函数存在问题,fcntl.lockf() 可使用但无法查询锁的所有者。
重要细节:
- sqlite3 使用 fcntl() 锁且不使用共享锁。
- fcntl 锁可检测死锁。
- MacOS 上三种锁由统一锁定实现处理,但其他系统不一定。
- mandatory 锁不可靠,可能导致问题。
- Python 中 fcntl.flock() 在无 flock() 的系统上通过调用 fcntl() 实现,fcntl.fcntl() 因数据结构问题不可用,fcntl.lockf() 是 fcntl() 的包装器。
- 作者在 Linux 上的程序工作正常,移植到 MacOS 后出现问题并提交 bug,MacOS 后来已修复。
- Linux 新增 F_OFD_SETLK 锁,Windows 10 WSL 中 fcntl 锁返回成功导致文件损坏。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。