文件锁


文件锁

概念

  • 在多进程对同一个文件进行读写访问时,为了保证数据的完整性,有时需要对文件进行锁定。
  • 可以通过fcntl()函数对文件进行锁定和解锁。
写锁(F_WRLCK独占锁)
  • 只有一个进程可以在文件的任一特定区域上享有独占锁。
读锁(F_RDLCK共享锁)
  • 许多不同的进程可以同时拥有文件上同一区域上的共享锁。

为了拥有共享锁,文件必须以 读 或者 读/写 的方式打开。只要任一进程拥有共享锁,那么其他进程就无法再获得独占锁。

flock()

  • 对整个文件进行操作
       #include <sys/file.h>

       int flock(int fd, int operation);
  • fd:文件描述符
  • operation 取值情况:
    • LOCK_SH:放置共享锁。在给定时间,多个进程可能持有给定文件的共享锁。
    • LOCK_EX:放置独占锁。在给定时间,只有一个进程可以为给定文件持有独占锁。
    • LOCK_UN:移除此进程持有的现有锁。

fcntl()

  • 可以对文件部分区域放锁。(精细版)
       #include <unistd.h>
       #include <fcntl.h>

       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
                                   (set by F_GETLK and F_OFD_GETLK) */
               ...
           };
  • 可变参数传struct flock结构体。
设置读锁
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>


int main() {

    int fd = open("./hello.txt", O_RDONLY);
    if (fd < 0) {
        perror("open");
        exit(1);
    }

    struct stat st;
    fstat(fd, &st);
    struct flock fl;
    fl.l_pid = getpid();
    fl.l_type = F_RDLCK;
    fl.l_start = 0;
    fl.l_whence = SEEK_SET;
    fl.l_len = st.st_size;

    printf("pid: %d ", fl.l_pid);
    if (fcntl(fd, F_SETLK, &fl) < 0) {
        perror("fcntl");
        exit(1);
    } else {
        printf("add read lock successfully\n");
    }

    sleep(10);
    close(fd);
    return 0;
}
设置写锁
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>


int main() {

    int fd = open("./hello.txt", O_WRONLY); //只写
    if (fd < 0) {
        perror("open");
        exit(1);
    }

    struct stat st;
    fstat(fd, &st); // 获取文件信息

    struct flock fl;
    fl.l_pid = getpid();
    fl.l_type = F_WRLCK; //设置写锁
    fl.l_start = 0;
    fl.l_whence = SEEK_SET;
    fl.l_len = st.st_size;

    printf("pid: %d ", fl.l_pid);
    while (fcntl(fd, F_SETLK, &fl) < 0) {
        perror("fcntl");
        struct flock fl2;
        fl2 = fl;
        fl2.l_type = F_WRLCK;

        fcntl(fd, F_GETLK, &fl2); //得到锁的信息
        switch (fl2.l_type) {
            case F_UNLCK:
                printf("get no lock\n");
                break;
            case F_RDLCK:
                printf("get read lock of pid = %d\n", fl2.l_pid);
                break;
            case F_WRLCK:
                printf("get write lock of pid = %d\n", fl2.l_pid);
                break;
        }
        sleep(1);

    }
    printf("add write lock successfully\n");

    getchar();
    close(fd);
    
    return 0;
}

文章作者: Axieyun
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Axieyun !
评论
评论
  目录