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 按位或使用,加锁失败不阻塞
- 基础示例:排他锁(写文件时加锁)
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;
}
- 非阻塞加锁(避免进程阻塞)
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;
}
- 共享锁(读文件时加锁)
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() 等替代。