文件锁 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
", (int)lock.l_start);
                    printf("l_len = %d
", (int)lock.l_len);
                    printf("l_pid = %d
", (int)lock.l_pid);
                    puts("F_WRLCK.");
                    break;
    }
} 

各种锁将在相应的文件描述符被关闭时自动清除

死锁现象
两个程序同一时间对字节1和字节2进行修改。程序A选择先修改字节2,再修改字节1,而程序B先修改字节1,再修改字节2
两个程序应该以同样的顺序对他们准备修改的字节施行封锁,或者对一个更大的文件区域实施封锁

3. O_APPEND
不加锁也可以,但需要O_APPEND选项

原文地址:https://www.cnblogs.com/zhangxuechao/p/11709725.html