文件级建议性锁函数flock

extern int flock (int __fd, int __operation) __THROW;

这个函数是 Linux 下进程间文件同步的基础工具,尤其适用于日志写入、配置文件修改等需要避免并发冲突的场景。
函数核心含义:

flock() 是 Unix/Linux 系统提供的文件级建议性锁函数(注意:不是强制性锁),用于对整个文件加锁 / 解锁,避免多进程 / 多线程同时操作文件导致数据错乱。

extern:表示函数声明来自外部(通常是系统库)

int __fd:文件描述符(通过 open() 或 dup() 等函数获取)

int __operation:锁操作指令(加锁 / 解锁 / 非阻塞加锁等)

__THROW:是 GCC 的宏,标识函数不会抛出 C++ 异常(仅编译提示)

返回值:成功返回 0,失败返回 - 1(并设置 errno)

关键参数:__operation(锁操作指令)

__operation 支持以下核心取值(需包含 <sys/file.h> 头文件):

LOCK_SH 共享锁(读锁):多个进程可同时加共享锁,适用于只读操作

LOCK_EX 排他锁(写锁):同一时间仅一个进程能加排他锁,适用于写操作

LOCK_UN 解锁:释放已持有的文件锁

LOCK_NB 非阻塞模式:和 LOCK_SH/LOCK_EX 按位或使用,加锁失败不阻塞

  1. 基础示例:排他锁(写文件时加锁)
cpp 复制代码
#include <iostream>
#include <fcntl.h>    // open()
#include <sys/file.h> // flock()
#include <unistd.h>   // write(), close()
#include <cstring>    // strerror()
#include <cerrno>     // errno
using namespace std;

int main() {
    // 1. 打开文件(读写模式,不存在则创建,权限0644)
    int fd = open("test.txt", O_RDWR | O_CREAT, 0644);
    if (fd == -1) {
        cerr << "打开文件失败:" << strerror(errno) << endl;
        return 1;
    }

    // 2. 加排他锁(阻塞模式:锁被占用时等待)
    if (flock(fd, LOCK_EX) == -1) {
        cerr << "加排他锁失败:" << strerror(errno) << endl;
        close(fd);
        return 1;
    }
    cout << "成功获取排他锁,开始写文件..." << endl;

    // 3. 写文件(临界区:确保只有当前进程操作)
    const char* content = "Hello, flock()!\n";
    write(fd, content, strlen(content));

    // 4. 模拟业务处理(比如睡眠5秒,验证锁的阻塞效果)
    sleep(5);

    // 5. 解锁
    if (flock(fd, LOCK_UN) == -1) {
        cerr << "解锁失败:" << strerror(errno) << endl;
        close(fd);
        return 1;
    }
    cout << "已释放锁" << endl;

    // 6. 关闭文件描述符
    close(fd);
    return 0;
}
  1. 非阻塞加锁(避免进程阻塞)
cpp 复制代码
#include <iostream>
#include <fcntl.h>
#include <sys/file.h>
#include <unistd.h>
#include <cstring>
#include <cerrno>
using namespace std;

int main() {
    int fd = open("test.txt", O_RDWR);
    if (fd == -1) {
        cerr << "打开文件失败:" << strerror(errno) << endl;
        return 1;
    }

    // 非阻塞排他锁:LOCK_EX | LOCK_NB
    if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
        if (errno == EWOULDBLOCK) { // 锁被占用
            cerr << "文件已被锁定,无法获取锁(非阻塞模式)" << endl;
        } else { // 其他错误
            cerr << "加锁失败:" << strerror(errno) << endl;
        }
        close(fd);
        return 1;
    }

    cout << "非阻塞模式获取锁成功" << endl;
    // 业务操作...
    flock(fd, LOCK_UN);
    close(fd);
    return 0;
}
  1. 共享锁(读文件时加锁)
cpp 复制代码
#include <iostream>
#include <fcntl.h>
#include <sys/file.h>
#include <unistd.h>
#include <cstring>
#include <cerrno>
using namespace std;

int main() {
    int fd = open("test.txt", O_RDONLY);
    if (fd == -1) {
        cerr << "打开文件失败:" << strerror(errno) << endl;
        return 1;
    }

    // 加共享锁(多个进程可同时获取)
    if (flock(fd, LOCK_SH) == -1) {
        cerr << "加共享锁失败:" << strerror(errno) << endl;
        close(fd);
        return 1;
    }

    cout << "获取共享锁,开始读文件..." << endl;
    // 读文件操作...
    
    flock(fd, LOCK_UN); // 解锁
    close(fd);
    return 0;
}

重要注意事项
建议性锁特性 :flock() 是 "建议性锁",即只有所有进程都遵守加锁规则时才有效;如果某个进程不调用 flock() 直接操作文件,锁会失效。
文件描述符生命周期 :锁和文件描述符绑定,关闭文件描述符(close())或进程退出时,内核会自动释放锁。
跨平台注意:flock() 是 Unix/Linux 特有,Windows 系统需用 LockFile() 等替代。

相关推荐
ADDDDDD_Trouvaille2 小时前
2026.2.13——OJ75-77题
c++·算法
近津薪荼2 小时前
dfs专题7—— 全排列
c++·学习·算法·深度优先
你的冰西瓜2 小时前
C++ STL算法——非修改序列算法
开发语言·c++·算法·stl
闻缺陷则喜何志丹2 小时前
P12275 [蓝桥杯 2024 国 Python B] 工厂|普及+
c++·算法·蓝桥杯·洛谷
星火开发设计2 小时前
类模板:实现通用数据结构的基础
java·开发语言·数据结构·c++·html·知识
寻寻觅觅☆3 小时前
东华OJ-基础题-122-循环数(C++)-难度难
开发语言·c++
王老师青少年编程3 小时前
2022年信奥赛C++提高组csp-s初赛真题及答案解析(完善程序第2题)
c++·题解·真题·初赛·信奥赛·csp-s·提高组
plus4s3 小时前
2月13日(73-75题)
数据结构·c++·算法
嵌入小生0073 小时前
进程(2)---相关函数接口、消亡、exec函数族 | 嵌入式(Linux)
linux·c语言·嵌入式·进程·函数接口·exec函数族·进程的消亡