文件锁 flock/fcntl
多个进程同时操作一个文件
1. flock
int flock(int fd, int operation);
LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定(读锁定)
LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定
LOCK_UN 解除文件锁定状态
LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合
2. fcntl
int fcntl(int fd, int cmd, ... /* arg */ );
struct flock {
...
short l_type; /* Type of lock: F_RDLCK,
F_WRLCK, F_UNLCK */
short l_whence; /* How to interpret l_start:
SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_start; /* Starting offset for lock */
off_t l_len; /* Number of bytes to lock */
pid_t l_pid; /* PID of process blocking our lock
(F_GETLK only) 持有锁 */
...
};
//lock set
struct flock lock = {0};
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 10;
ret = fcntl(fd, F_SETLK, &lock);
ret = fcntl(fd, F_SETLKW, &lock); //阻塞模式
//lock get
if((ret = fcntl(fd, F_GETLK, &lock)) == 0)
{
switch(lock.l_type)
{
case F_UNLCK:
puts("F_UNLCK.");
break;
case F_RDLCK:
puts("F_RDLCK.");
break;
case F_WRLCK:
printf("l_start = %d\n", (int)lock.l_start);
printf("l_len = %d\n", (int)lock.l_len);
printf("l_pid = %d\n", (int)lock.l_pid);
puts("F_WRLCK.");
break;
}
}
各种锁将在相应的文件描述符被关闭时自动清除
死锁现象
两个程序同一时间对字节1和字节2进行修改。程序A选择先修改字节2,再修改字节1,而程序B先修改字节1,再修改字节2
两个程序应该以同样的顺序对他们准备修改的字节施行封锁,或者对一个更大的文件区域实施封锁
3. O_APPEND
不加锁也可以,但需要O_APPEND选项