nfs 锁机制demo

下面我将提供几个不同的 C++ 示例,分别测试以下场景:

  1. 单个机器多个进程读取共享文件,锁是否有效
  2. 一个机器写入共享文件,另一个机器同时读取共享文件,锁是否有效
  3. 多个机器同时读取共享文件,锁是否有效
  4. 一个机器同时多个接口写入共享文件,锁是否有效
    每个场景都依赖于 POSIX 文件锁(fcntl())来管理文件的读写锁。锁在 NFS 文件系统上通常能确保数据的正确同步,但多个机器访问时,网络延迟和 NFS 配置可能会影响锁的行为,因此要注意环境配置。

1. 单个机器多个进程读取共享文件,锁是否有效

这个代码验证了在同一台机器上,多个进程是否能正确地读取文件并获得锁。

cpp 复制代码
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <cstring>
#include <errno.h>

#define FILE_PATH "/mnt/nfs/myfile.txt"

void acquire_read_lock(int fd) {
    struct flock lock;
    lock.l_type = F_RDLCK;  // 读锁
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;  // 锁定整个文件

    if (fcntl(fd, F_SETLK, &lock) == -1) {
        std::cerr << "读锁加锁失败: " << strerror(errno) << std::endl;
        exit(1);
    }
    std::cout << "获得读锁" << std::endl;
}

void release_lock(int fd) {
    struct flock lock;
    lock.l_type = F_UNLCK;  // 释放锁
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;

    if (fcntl(fd, F_SETLK, &lock) == -1) {
        std::cerr << "释放锁失败: " << strerror(errno) << std::endl;
    }
    std::cout << "锁已释放" << std::endl;
}

int main() {
    int fd = open(FILE_PATH, O_RDWR | O_CREAT, 0666);
    if (fd == -1) {
        std::cerr << "文件打开失败: " << strerror(errno) << std::endl;
        return 1;
    }

    // 创建多个进程来模拟并发读取
    pid_t pid = fork();
    if (pid == 0) {
        acquire_read_lock(fd);
        std::cout << "子进程 1 正在读取文件..." << std::endl;
        sleep(5);
        release_lock(fd);
        exit(0);
    }

    pid = fork();
    if (pid == 0) {
        acquire_read_lock(fd);
        std::cout << "子进程 2 正在读取文件..." << std::endl;
        sleep(5);
        release_lock(fd);
        exit(0);
    }

    wait(NULL);
    wait(NULL);

    close(fd);
    return 0;
}

2. 一个机器写入共享文件,另一个机器同时读取共享文件,锁是否有效

在这个场景中,模拟一台机器进行写入,另一台机器进行读取。需要在不同机器上运行这个代码。
写入机器:

cpp 复制代码
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <errno.h>

#define FILE_PATH "/mnt/nfs/myfile.txt"

void acquire_write_lock(int fd) {
    struct flock lock;
    lock.l_type = F_WRLCK;  // 写锁
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;

    if (fcntl(fd, F_SETLK, &lock) == -1) {
        std::cerr << "写锁加锁失败: " << strerror(errno) << std::endl;
        exit(1);
    }
    std::cout << "获得写锁" << std::endl;
}

void release_lock(int fd) {
    struct flock lock;
    lock.l_type = F_UNLCK;  // 释放锁
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;

    if (fcntl(fd, F_SETLK, &lock) == -1) {
        std::cerr << "释放锁失败: " << strerror(errno) << std::endl;
    }
    std::cout << "锁已释放" << std::endl;
}

int main() {
    int fd = open(FILE_PATH, O_RDWR | O_CREAT, 0666);
    if (fd == -1) {
        std::cerr << "文件打开失败: " << strerror(errno) << std::endl;
        return 1;
    }

    acquire_write_lock(fd);
    std::cout << "写入操作进行中..." << std::endl;
    sleep(5);  // 模拟写入操作
    release_lock(fd);

    close(fd);
    return 0;
}

读取机器(同上,使用第一个示例)。

3. 多个机器同时读取共享文件,锁是否有效

在这个场景中,多个机器同时进行读取文件的操作,可以在不同机器上运行第一个示例。NFS 文件系统通常允许多个进程同时读取文件,只要它们持有读锁时不会相互干扰。

4. 一个机器同时多个接口写入共享文件,锁是否有效

这个场景模拟了在同一台机器上,通过多个进程进行写入操作,并验证锁是否有效。使用与第二个场景类似的代码,但通过多个进程进行并发写入。

cpp 复制代码
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <errno.h>
#include <sys/wait.h>

#define FILE_PATH "/mnt/nfs/myfile.txt"

void acquire_write_lock(int fd) {
    struct flock lock;
    lock.l_type = F_WRLCK;  // 写锁
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;

    if (fcntl(fd, F_SETLK, &lock) == -1) {
        std::cerr << "写锁加锁失败: " << strerror(errno) << std::endl;
        exit(1);
    }
    std::cout << "获得写锁" << std::endl;
}

void release_lock(int fd) {
    struct flock lock;
    lock.l_type = F_UNLCK;  // 释放锁
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;

    if (fcntl(fd, F_SETLK, &lock) == -1) {
        std::cerr << "释放锁失败: " << strerror(errno) << std::endl;
    }
    std::cout << "锁已释放" << std::endl;
}

int main() {
    int fd = open(FILE_PATH, O_RDWR | O_CREAT, 0666);
    if (fd == -1) {
        std::cerr << "文件打开失败: " << strerror(errno) << std::endl;
        return 1;
    }

    pid_t pid1 = fork();
    if (pid1 == 0) {
        acquire_write_lock(fd);
        std::cout << "子进程 1 正在写入文件..." << std::endl;
        sleep(5);
        release_lock(fd);
        exit(0);
    }

    pid_t pid2 = fork();
    if (pid2 == 0) {
        acquire_write_lock(fd);
        std::cout << "子进程 2 正在写入文件..." << std::endl;
        sleep(5);
        release_lock(fd);
        exit(0);
    }

    wait(NULL);
    wait(NULL);

    close(fd);
    return 0;
}


g++ -o file_lock_demo file_lock_demo.cpp
./file_lock_demo

注意事项:

  • 需要在 NFS 配置中确保锁机制开启,并且文件系统配置正确。
  • 测试时,建议在不同的机器上执行这些进程,尤其是在写入和读取操作之间的锁竞争。
  • 为了确保锁机制的有效性,确保使用的 NFS 服务器支持锁定(如 lockd 服务必须启动)。
    这些代码分别模拟了不同机器和进程间的锁竞争,通过加锁机制保证了文件的并发访问正确性。运行这些代码时,确保在 NFS 环境中进行测试。
相关推荐
SEO_juper21 分钟前
Go 站点地图生成器:从首页爬全站,一键生成 sitemap.xml
xml·开发语言·人工智能·golang·node.js·seo·外贸独立站
懂点Tech8 小时前
ctfshow misc28:GIF 高度修改解题与脚本实现
开发语言·windows·python
云和数据.ChenGuang8 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
美狐美颜SDK开放平台9 小时前
视频美颜SDK试用DEMO阶段应该测试什么?直播APP接入实操指南
开发语言·人工智能·深度学习·音视频·美颜sdk·直播美颜sdk·第三方美颜sdk
dtq04249 小时前
C++小案例 - 日志实战
开发语言·c++
星夜离尘5610 小时前
MATLAB ADC 码流触顶诊断:命中数、缺口分段与削顶不可辨识性
开发语言·matlab
码匠许师傅10 小时前
【C++三方组件】Qt 概览:桌面 C++ 的事实标准与许可证三轨
开发语言·c++·qt
码匠许师傅11 小时前
【C++三方组件】POCO:跨平台系统编程全家桶
开发语言·c++
bkspiderx12 小时前
基于Socket的广播通信及C语言实现详解
c语言·开发语言·socket·广播·socket的广播通信
小王C语言12 小时前
Qt常用控件:输入类控件,单行/多行输入框、下拉框、(日期)微调框、旋钮、滑动条
开发语言·qt