0

0

C++如何实现对文件的读写锁定以用于多线程环境

P粉602998670

P粉602998670

发布时间:2025-09-09 11:43:01

|

1095人浏览过

|

来源于php中文网

原创

答案:多线程文件读写需加锁防止数据损坏,C++中可使用操作系统提供的flock()或LockFileEx()实现跨进程文件锁,或用std::mutex进行进程内线程同步,前者适用于多进程场景,后者仅限单进程;需注意锁机制不可混用、锁与文件描述符关联、NFS等文件系统支持不完整等问题,且应显式释放锁避免异常。

c++如何实现对文件的读写锁定以用于多线程环境

在多线程环境中对文件进行读写时,如果不加控制,多个线程可能同时修改文件内容,导致数据损坏或读取到不一致的状态。C++ 标准库本身没有提供跨平台的文件锁定机制,但可以通过操作系统提供的系统调用来实现文件的读写锁定。以下是常见的实现方式和建议。

使用操作系统提供的文件锁机制

文件锁定通常依赖于操作系统的支持。Linux 和类 Unix 系统提供 flock()fcntl() 系统调用,Windows 提供 LockFile()LockFileEx()。这些机制可以实现对整个文件或部分区域的读(共享)锁和写(独占)锁。

Linux 示例:使用 flock()

flock() 是较简单的文件锁接口,支持共享锁(读锁)和独占锁(写锁)。

立即学习C++免费学习笔记(深入)”;

示例代码:

#include 
#include 
#include 
#include 
#include 

void write_with_lock(const std::string& filename) { int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0644); if (fd == -1) { perror("open"); return; }

// 请求独占写锁(阻塞直到获取)
if (flock(fd, LOCK_EX) == -1) {
    perror("flock write");
    close(fd);
    return;
}

// 写入数据
const char* msg = "Hello from thread\n";
write(fd, msg, strlen(msg));

// 释放锁(关闭文件描述符也会自动释放)
flock(fd, LOCK_UN);
close(fd);

}

void read_with_lock(const std::string& filename) { int fd = open(filename.c_str(), O_RDONLY); if (fd == -1) { perror("open"); return; }

// 请求共享读锁
if (flock(fd, LOCK_SH) == -1) {
    perror("flock read");
    close(fd);
    return;
}

// 读取文件内容
std::string content;
char buffer[256];
ssize_t n;
while ((n = read(fd, buffer, sizeof(buffer) - 1)) > 0) {
    buffer[n] = '\0';
    content += buffer;
}
std::cout << content;

flock(fd, LOCK_UN);
close(fd);

}

Windows 示例:使用 LockFileEx()

Windows 使用重叠 I/O 结构进行文件锁定,支持更细粒度的控制。

AI Room Planner
AI Room Planner

AI 室内设计工具,免费为您的房间提供上百种设计方案

下载

示例代码片段:

#include 
#include 

void write_with_windows_lock(const std::string& filename) { HANDLE hFile = CreateFile( filename.c_str(), GENERIC_WRITE, 0, // 不共享,实现独占访问 NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );

if (hFile == INVALID_HANDLE_VALUE) return;

// 锁定整个文件
OVERLAPPED overlap = {0};
LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, MAXDWORD, MAXDWORD, &overlap);

SetFilePointer(hFile, 0, NULL, FILE_END);
std::string data = "Hello from Windows thread\n";
DWORD written;
WriteFile(hFile, data.c_str(), data.length(), &written, &overlap);

UnlockFileEx(hFile, 0, MAXDWORD, MAXDWORD, &overlap);
CloseHandle(hFile);

}

使用 C++ 线程互斥量(mutex)进行进程内协调

如果所有线程都在同一个进程中,可以使用 std::mutex 来保护对文件的操作。这种方法简单高效,但仅限于同一进程内的线程同步。

示例:

#include 
#include 
#include 

std::mutex file_mutex;

void safe_write(const std::string& filename, const std::string& data) { std::lock_guard lock(file_mutex); std::ofstream file(filename, std::ios::app); file << data << std::endl; }

这种方法不能防止其他进程修改文件,只适用于单进程多线程场景。

跨进程文件锁的注意事项

使用系统级文件锁时,注意以下几点:

  • flock() 和 fcntl() 不可混用,应统一使用一种机制。
  • 文件锁通常与文件描述符关联,fork() 后子进程继承锁,但多线程中每个线程打开的文件是独立的 fd。
  • 建议始终在 close() 前显式解锁,避免意外行为。
  • 某些文件系统(如 NFS)对文件锁支持不完整,需测试验证。

基本上就这些。选择哪种方式取决于是否需要跨进程保护。同一进程内用 std::mutex 最简单;多进程环境则需系统级文件锁。不复杂但容易忽略的是锁的粒度和释放时机。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

483

2023.08.02

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

780

2023.08.22

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

531

2023.09.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

483

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

545

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

113

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

200

2025.08.29

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

177

2023.11.23

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8.1万人学习

Git 教程
Git 教程

共21课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号