Linux应用程序的一个常见需求是从一个文件中读取一些数据,修改这些数据,然后将这些数据写回文件。只要在一个时刻只有一个进程以这种方式使用文件就不会存在问题,但当多个进程同时更新一个文件时问题就出现了(会导致文件的内容不是按照我们的预期进行存储)。
在Linux中,文件加锁是通过使用文件锁(File Locks)来实现的。文件锁主要有两种类型:共享锁(Shared Lock)和排他锁(Exclusive Lock)。这些锁用于控制对文件的并发访问,以防止多个进程同时对同一文件进行读或写操作,从而保护文件的一致性。
1. 共享锁(读锁 - Shared Lock)
F_RDLCK
或LOCK_SH
表示。2. 排他锁(写锁 - Exclusive Lock)
F_WRLCK
或LOCK_EX
表示。3. 解锁
F_UNLCK
或LOCK_UN
表示,用于释放已经获取的锁。1. 阻塞锁定
2. 非阻塞锁定
1. 进程间锁
2. 线程间锁
1. 进程关闭时解锁
2. 文件关闭时解锁
在 Linux 中,文件锁是通过系统调用 fcntl
或者 flock
来实现的。
fcntl
进行文件锁定unsetunset1. 锁定整个文件
#include <fcntl.h>
struct flock fl;
fl.l_type = F_WRLCK; // 或 F_RDLCK 代表读锁
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0; // 锁定整个文件
fcntl(fd, F_SETLKW, &fl); // F_SETLKW 表示阻塞方式设置锁
2. 解锁整个文件
fl.l_type = F_UNLCK;
fcntl(fd, F_SETLK, &fl);
3. 锁定文件的一部分
fl.l_type = F_WRLCK; // 或 F_RDLCK 代表读锁
fl.l_whence = SEEK_SET;
fl.l_start = 100; // 从文件的偏移量 100 处开始锁定
fl.l_len = 50; // 锁定 50 个字节
fcntl(fd, F_SETLKW, &fl);
flock
进行文件锁定unsetunset1. 锁定整个文件
#include <fcntl.h>
flock(fd, LOCK_EX); // LOCK_EX 代表排他锁
2. 解锁整个文件
flock(fd, LOCK_UN);
3. 锁定文件的一部分
flock
不支持锁定文件的一部分。
fcntl
可以实现更复杂的锁定策略,例如非阻塞锁定、记录锁定等。fcntl
锁定是进程级别的,不同进程的文件锁互不影响;而 flock
锁定是进程组级别的,一个进程组中的锁定会影响到同一进程组的其他进程。文件锁是多进程或多线程环境下对文件进行同步的一种有效方式,可以防止多个进程同时修改同一文件导致的问题。在实际应用中,根据具体需求和环境选择适合的文件锁定方式。