Python并发写文件需用锁防竞态:线程间用threading.Lock,进程间用multiprocessing.Lock;也可用队列中转、原子追加或logging模块替代。

多个线程或进程同时向同一个文件写入数据时,不加控制会导致内容错乱、覆盖甚至损坏。Python 中实现安全的并发文件写入,核心在于“避免竞态条件”——即确保同一时刻最多只有一个写操作在执行。这需要借助锁(Lock)或更高级的同步机制,但具体选哪种、怎么用,得看你是线程内并发还是跨进程并发。
线程间写入:用 threading.Lock 最直接
同一进程内的多个线程共享内存和文件描述符,直接 open/write 会互相干扰。解决办法是在写入前加锁,写完释放:
- 创建一个全局 threading.Lock() 实例(不能每个线程新建一个)
- 所有写操作必须包裹在 lock.acquire() / lock.release() 或更推荐的 with lock: 块中
- 注意:锁只保护你的代码逻辑,不自动保护底层系统调用;但对普通文本写入已足够
示例片段:
lock = threading.Lock()def write_to_file(content):
with lock:
with open("log.txt", "a") as f:
f.write(content + "\n")
多进程写入:不能用 threading.Lock,改用 multiprocessing.Lock
子进程不共享线程锁对象,threading.Lock 在 multiprocessing 中完全无效。必须使用 multiprocessing.Lock,它基于系统级原语(如 semaphores),可在进程间同步:
立即学习“Python免费学习笔记(深入)”;
- 在主进程中创建 multiprocessing.Lock(),作为参数传给子进程或通过 Manager 共享
- 子进程中同样用 with lock: 确保临界区互斥
- 若需更高性能且写入量大,可考虑让各进程写入独立临时文件,最后由主进程合并
更轻量替代方案:避免锁,用原子写入或队列中转
不是所有场景都必须锁文件。以下方式可绕过同步复杂度:
- 单生产者多消费者? 用 queue.Queue(线程安全)或 multiprocessing.Queue 收集写入请求,由一个专属线程/进程顺序落盘
- 追加写(append)+ 小数据? Linux/macOS 下 open(..., "a") 的 write 是原子的(只要单次写入 ≤ 4KB),但仅限追加,且不保证多行原子性
- 日志类场景? 直接用标准库 logging 模块,它内置了线程安全的 FileHandler,支持多线程写入
常见误区提醒
容易忽略但影响稳定的细节:
- 用 "w" 模式打开文件会清空内容,多线程/进程下极易丢失数据 —— 追加一律用 "a"
- 文件对象本身不是线程安全的,即使加了锁,也要确保每次写都重新 open / close,或复用同一个 file 对象(但后者需更谨慎管理生命周期)
- 异步 IO(asyncio)中不能直接用 threading.Lock,应改用 asyncio.Lock,且需配合 async with










