原子性与竞争
文件操作中的原子性问题是并发编程和系统编程中的重要考量。非原子操作序列可能被其他进程中断,导致不可预测的结果。
原子性操作:
- 原子操作要么完全执行,要么完全不执行,中间状态对外不可见。
- 内核保证某些操作是原子的,如
open的O_CREAT | O_EXCL组合:若文件不存在则创建,存在则返回错误,这两个操作之间不会被其他进程中断。
竞争条件(Race Condition):
- 当多个进程并发访问共享资源,且结果依赖于执行顺序时,就会发生竞争条件。
- 经典竞争场景——临时文件创建:
- 不安全的做法:先
access检查文件是否存在,再创建。两操作间可能被其他进程插入。 - 安全的做法:使用
O_CREAT | O_EXCL一次性原子地创建文件。
- 不安全的做法:先
文件读写中的原子性:
read和write本身不是原子的(对普通文件)。- 但内核保证小于
PIPE_BUF的管道写操作是原子的。 - 多线程或多进程同时对同一文件进行
read/write时,数据可能交错。
避免竞争的正确做法是使用原子操作和同步机制,而不是”先检查后执行”的模式(TOCTOU race)。
链接到
- 上一个知识点:10.10 共享文件
- 下一个知识点:10.12 dup重定向