文件级建议性锁函数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() 等替代。

相关推荐
坚果派·白晓明1 天前
【鸿蒙PC三方库移植适配框架解读系列】第八篇:扩展lycium框架使其满足rust三方库适配
c语言·开发语言·华为·rust·harmonyos·鸿蒙
REDcker1 天前
C++变量存储与ELF段布局详解 从const全局到rodata与nm_readelf验证实践
java·c++·面试
谙弆悕博士1 天前
快速学C语言——第16章:预处理
c语言·开发语言·chrome·笔记·创业创新·预处理·业界资讯
matlabgoodboy1 天前
软件开发定制小程序APP帮代做java代码代编写C语言设计python编程
java·c语言·小程序
王老师青少年编程1 天前
csp信奥赛C++高频考点专项训练之字符串 --【字符串排序】:合并序列
c++·字符串·csp·高频考点·信奥赛·字符串排序·合并序列
handler011 天前
UDP协议与网络通信知识点
c语言·网络·c++·笔记·网络协议·udp
神仙别闹1 天前
基于QT(C++)实现学生成绩管理系统
数据库·c++·qt
C+++Python1 天前
C 语言 动态内存分配:malloc /calloc/realloc /free
c语言·开发语言
cen__y1 天前
Linux11(网络编程)
linux·运维·服务器·c语言·网络·网络协议·tcp/ip
君义_noip1 天前
CSP-S 2025 入门级 第一轮(初赛) 完善程序(1)
c++·算法·信息学奥赛·初赛·csp 第一轮