在多进程对同一个文件进行读写访问时,为了保证数据的完整性,有时需要对文件进行锁定。可以通过fcntl()函数对文件进行锁定和解锁。

对于写锁(F_ WRLCK独占锁),只有一个进程可以在文件的任一特定区域上享有独占锁。对于读锁(F_RDLCK共享锁),许多不同的进程可以同时拥有文件上同区域上的共享锁。为了拥有共享锁,文件必须以或者读/写的方式打开。只要任一进程拥有共享锁,那么其他进程就无法再获得独占锁。

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

/**
 * @brief 给文件hello.txt上一把读锁
 * 
 * @param argc 
 * @param argv 
 * @return int 
 */
int main(int argc, char const *argv[]) {
    int fd = open("./hello.txt", O_RDONLY);
    if (fd < 0) {
        perror("open\n");
        exit(-1);
    }

    struct stat stat;
    fstat(fd, &stat);

    struct flock lock;
    lock.l_type = F_RDLCK;     //类型:读锁,是共享锁
    lock.l_pid = getpid();     //pid
    lock.l_whence = SEEK_SET;  //锁住内容的起点:SEEK_SET文件开始
    lock.l_start = 0;          //偏移量
    lock.l_len = stat.st_size;

    printf("pid: %d ", lock.l_pid);
    if (fcntl(fd, F_SETLK, &lock) < 0) {
        perror("fcntl\n");
        exit(-2);
    }

    printf("add a read lock successfully\n");
    sleep(10);

    close(fd);

    return 0;
}
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

/**
 * @brief 给文件hello.txt上一把读锁
 * 
 * @param argc 
 * @param argv 
 * @return int 
 */
int main(int argc, char const *argv[]) {
    int fd = open("./hello.txt", O_RDONLY);
    if (fd < 0) {
        perror("open\n");
        exit(-1);
    }

    struct stat stat;
    fstat(fd, &stat);

    struct flock lock;
    lock.l_type = F_RDLCK;     //类型:读锁,是共享锁
    lock.l_pid = getpid();     //pid
    lock.l_whence = SEEK_SET;  //锁住内容的起点:SEEK_SET文件开始
    lock.l_start = 0;          //偏移量
    lock.l_len = stat.st_size;

    printf("pid: %d ", lock.l_pid);
    if (fcntl(fd, F_SETLK, &lock) < 0) {
        perror("fcntl\n");
        exit(-2);
    }

    printf("add a read lock successfully\n");
    sleep(10);

    close(fd);

    return 0;
}