flock最省心,简单可靠且自动释放;fcntl易误用,Windows不支持;msvcrt.locking仅锁文件区域;跨平台推荐portalocker;锁文件不等于防并发写,需配合原子写入等机制。

Linux/macOS 用 flock 最省心,别硬上 fcntl
绝大多数场景下,flock 就是你要的“文件锁”——它简单、可靠、自动释放,且不依赖文件描述符生命周期。而 fcntl 的 F_SETLK 虽然更底层,但容易误用:比如没检查返回值、忽略 EAGAIN、或在 fork 后意外继承锁导致死锁。
-
flock是建议性锁,但只要所有进程都遵守,行为就确定;fcntl锁也属建议性,且需手动管理struct flock,出错概率高 - Python 标准库
fcntl模块在 Windows 上根本不可用,跨平台时直接报ModuleNotFoundError - 若必须用
fcntl(如需要共享锁/读锁),务必捕获OSError并检查.errno == errno.EAGAIN,不能只看返回值是否为 -1
Windows 只能靠 msvcrt.locking,但它只锁文件区域,不是全文件
msvcrt.locking 不是“加一把锁”,而是对文件某一段字节做独占标记。它不阻塞,失败直接抛 IOError(errno == 33 表示已被锁),而且锁在文件描述符关闭时自动释放——这点和 flock 一致,但语义完全不同。
- 必须先用
os.open(..., os.O_RDWR)打开文件,open()返回的 file object 不支持msvcrt.locking - 锁区域从当前文件偏移开始,长度由第三个参数指定;锁
0字节等于锁整个文件(实践中常用) - 无法实现“等待锁释放”的逻辑,只能轮询 + sleep,否则会立刻失败
跨平台封装别自己写,用 portalocker 库最稳
自己判断平台、选函数、处理异常、重试逻辑,很容易漏掉边界情况。比如 Windows 下 msvcrt 锁不支持进程外继承,而 Linux 下 flock 在 fork 后父子进程共享锁,这些差异光靠 if-else 很难兜住。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
-
portalocker把flock/msvcrt.locking/win32file.LockFileEx(可选)统一成lock/unlock接口 - 支持阻塞等待(
timeout=5)、非阻塞(timeout=0)、以及自动上下文管理(with portalocker.Lock(...)) - 注意:它默认不使用
win32file,除非你装了pywin32,否则 Windows 下仍是msvcrt行为
锁文件 ≠ 防止并发写,关键在“打开方式”和“写入时机”
很多人以为加了锁就万事大吉,结果发现两个进程还是写串了。根本原因在于:锁只保证“同一时刻只有一个进程在持锁”,但不控制你什么时候调用 f.write()、是否 flush、是否原子写入。
立即学习“Python免费学习笔记(深入)”;
- 用
os.open(..., os.O_WRONLY | os.O_CREAT | os.O_EXCL)创建临时文件再 rename,比锁一个长期存在的配置文件更可靠 - 避免在锁内做耗时操作(如网络请求、复杂计算),否则其他进程会长时间等待
-
flock和msvcrt.locking都不阻止 unlink,所以锁着的文件被删了,锁依然存在(Linux)或失效(Windows),行为不一致

















