Bootstrap

C语言文件锁Linux

在C语言中,flock 是一个用于文件锁定的函数,定义在 sys/file.h 头文件中。它的主要目的是在对文件进行读写操作时,避免其他进程同时访问文件,以实现文件的并发控制。

flock 函数的原型

#include <sys/file.h>

int flock(int fd, int operation);

参数

  • fd: 文件描述符,通常通过 open 函数获得。
  • operation: 锁定操作的类型,通常是以下几种之一:
    • LOCK_SH: 共享锁,允许其他进程读取文件,但不允许写入。
    • LOCK_EX: 排他锁,阻止其他进程读取或写入文件。
    • LOCK_UN: 解锁,释放之前的锁。
    • LOCK_NB: 非阻塞模式,锁定操作不会被阻塞,如果锁定失败,flock 立即返回错误。

返回值

  • 成功:返回 0
  • 失败:返回 -1,并设置 errno 以指示错误原因。

示例

进程A1写入完成前,进程A2的写入被阻塞,进程A3的读取被阻塞。

A1.c

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <unistd.h>
int main() {
    int fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fd < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 加锁
    if (flock(fd, LOCK_EX) < 0) {
        perror("flock");
        close(fd);
        exit(EXIT_FAILURE);
    }

    printf("File is locked. Performing operations...\n");
    const char *message = "Hello, World!\n"; // 要写入的数据
    // 写入数据
    ssize_t bytesWritten = write(fd, message, strlen(message));
    if (bytesWritten < 0) {
        perror("write");
        close(fd);
        exit(EXIT_FAILURE);
    } else {
        printf("Successfully wrote %ld bytes to the file.\n", bytesWritten);
    }
    sleep(10);
    // 简化写入过程不做成功判断 仅测试用
    const char *endmsg = "The End!\n";
    write(fd, endmsg, strlen(endmsg));
    printf("writing finished\n");

    // 解锁
    if (flock(fd, LOCK_UN) < 0) {
        perror("flock");
        close(fd);
        exit(EXIT_FAILURE);
    }

    close(fd);
    return 0;
}

A2.c

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <unistd.h>
int main() {
    int fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fd < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 加锁
    if (flock(fd, LOCK_EX) < 0) {
        perror("flock");
        close(fd);
        exit(EXIT_FAILURE);
        }

    // 简化写入过程不做成功判断 仅测试用
    const char *newmsg = "new msg!\n";
    write(fd, newmsg, strlen(newmsg));

    // 解锁
    if (flock(fd, LOCK_UN) < 0) {
        perror("flock");
        close(fd);
        exit(EXIT_FAILURE);
    }

    close(fd);
    return 0;
}

A3.c

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

#define BUFFER_SIZE 256

int main() {
    // 打开文件以只读模式
    int fd = open("example.txt", O_RDONLY);
    if (fd < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 获取共享锁
    if (flock(fd, LOCK_SH) < 0) {
        perror("flock");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 读取数据
    char buffer[BUFFER_SIZE];
    ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1);
    if (bytesRead < 0) {
        perror("read");
        flock(fd, LOCK_UN); // 解锁
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 读取到的数据添加终止符
    buffer[bytesRead] = '\0';

    // 输出读取的数据
    printf("Read from file: %s\n", buffer);

    // 解锁
    if (flock(fd, LOCK_UN) < 0) {
        perror("flock");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 关闭文件
    close(fd);
    return 0;
}

;