Linux并发文件读写总结
多个进程对同一文件进行读写
- 同时读是没有任何问题的
- 读写、写写需要加文件锁,fcntl、flock函数为相应的系统调用。文件锁是与进程相关的,一个进程中的多个线程/协程对同一个文件进行的锁操作会互相覆盖掉
- 对于写写,有一种例外的情况,使用 O_APPEND 标志来打开文件,这样在每次写入时都会 lseek 到文件末尾进行写入,这是一个原子操作,因此不会产生同步问题
多线程情况
-
多次打开同一文件是由实现定义的,有的实现不支持这种行为,所以不要在一个程序中多次打开同一文件。所以以下讨论的都是对同一fd的竞争情况
-
C语言标准库中的io函数(fread、fwrite、fseek)大多是线程安全的,另外还有一组不加锁的版本,以_unlocked为后缀
size_t fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) { size_t ret; FLOCKFILE(fp); ret = __fread(buf, size, count, fp); FUNLOCKFILE(fp); return (ret); }
-
linux下write操作,使用O_APPEND选项给文件追加数据,是线程安全的。对于管道io(fifo/重定向/NFS等),如果write大小不超过PIPE_BUF的话保证是原子操作,大小超过PIPE_BUF不保证原子性