C++多进程下使用文件锁互斥执行压缩进程

文章目录

    • 0. 引言
    • 1. 解决方案
    • 2. 文件锁相比信号量的优势
    • 3. 示例代码compress_log.cpp
    • 4. 流程图
    • 5. 总结

0. 引言

在多进程环境中,每个进程都会生成自己的日志文件,并独立进行gzip压缩。尽管每个进程压缩的频率和时间可能不同,但由于系统的运行特性,极少数情况下多个进程可能同时尝试压缩各自的日志文件。这种情况下,如果不加以控制,可能会导致多个压缩实例同时进行,从而引起CPU使用率瞬间超过阈值,甚至可能导致系统发生不可控行为。

1. 解决方案

为了避免多个进程同时压缩日志文件所引发的潜在问题,我们需要引入一种有效的同步机制来控制压缩实例的并发性。文件锁作为一种经典的同步解决方案,在这种场景下尤为适用。文件锁能够确保在任何时刻只有一个进程能够持有特定文件的锁,从而有效地限制并发压缩实例的数量,确保系统资源的合理利用和稳定运行。

2. 文件锁相比信号量的优势

  • 持久性和跨进程支持: 文件锁能够在不同的进程之间进行同步和互斥控制,而且通常是持久性的,即使系统重启后仍然有效。

  • 不受单个进程生命周期限制: 文件锁不像信号量在进程结束时释放,而是可以持久化存在;任意进程异常终止时仍能保持一致性。

  • 简单易用: 文件锁具备简单易用的接口。

  • 粗粒度文件控制: 文件锁可以控制文件级别的访问,使得可以精确地控制对于文件资源的并发访问。

3. 示例代码compress_log.cpp

以下是使用文件锁在C++中实现压缩日志的示例代码

#include <iostream>
#include <fstream>
#include <thread>
#include <mutex>
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>// 函数声明
void compress_log(const std::string& log_file_name);
void compress_log_safety(const std::string& log_file_name);// 全局变量
std::mutex log_mutex;// 压缩日志的具体逻辑
void compress_log(const std::string& log_file_name) {std::string gz_file_name = log_file_name + ".gz";// 打开源文件std::ifstream source(log_file_name, std::ios::binary);if (!source) {std::cerr << "Failed to open source file: " << std::strerror(errno) << std::endl;return;}// 打开目标文件(使用gzFile,这里简化处理)auto gzdest = std::unique_ptr<gzFile_s, decltype(&gzclose)>(gzopen(gz_file_name.c_str(), "wb"), gzclose);if (!gzdest) {std::cerr << "Failed to open destination file" << std::endl;source.close();return;}// 复制数据从源到目标constexpr std::size_t buffer_size = 1024;char buffer[buffer_size];int bytes_read;while ((bytes_read = source.readsome(buffer, buffer_size)) > 0) {if (gzwrite(gzdest.get(), buffer, bytes_read) != bytes_read) {std::cerr << "Failed to write to destination file" << std::endl;source.close();return;}}// 关闭文件source.close();// 删除原始日志文件if (std::remove(log_file_name.c_str()) != 0) {std::cerr << "Failed to remove original log file: " << std::strerror(errno) << std::endl;}
}// 使用文件锁来保证安全地压缩日志
void compress_log_safety(const std::string& log_file_name) {std::lock_guard<std::mutex> lock(log_mutex);// 打开锁文件int lock_fd = open("/tmp/log_lockfile", O_CREAT | O_RDWR, 0644);if (lock_fd == -1) {std::cerr << "Failed to open lock file: " << std::strerror(errno) << std::endl;return;}// 锁定文件if (flock(lock_fd, LOCK_EX) == -1) {std::cerr << "Failed to lock file: " << std::strerror(errno) << std::endl;close(lock_fd);return;}// 在锁定状态下执行压缩日志操作compress_log(log_file_name);// 解锁并释放文件锁flock(lock_fd, LOCK_UN);close(lock_fd);
}int main() {std::string log_file = "example.log";compress_log_safety(log_file);return 0;
}

4. 流程图

以下是压缩日志的简化流程图,展示了从获取文件锁到压缩日志文件的过程:

Start
Open Lock File
Lock File
Compress Log
Unlock File
End

5. 总结

在多进程环境中,使用文件锁来实现对各自日志文件的安全访问和压缩是一种推荐的做法。文件锁能够有效控制并发压缩实例的数量,确保每次压缩操作的安全性和可靠性,从而避免潜在的竞态条件和数据不一致性问题的发生。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/40559.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Arduino】ESP8266开发环境配置(图文)

ESP8266与ESP32开发很类似&#xff0c;相当于是低配版本的ESP32&#xff0c;其同样具有无线网络连接能力&#xff0c;功能强大&#xff0c;而且价格比ESP32更具有优势。接下来我们就来设置一下ESP8266的开发环境。 使用Arduino开发平台软件&#xff0c;选择首选项进行设置。 h…

ASP.NET Core 6.0 使用 Action过滤器

Action过滤器 在ASP.NET Core中&#xff0c;Action过滤器用于在执行Action方法之前或之后执行逻辑。你可以创建自定义的Action过滤器来实现这一点。 继承 ActionFilterAttribute 类&#xff1a; [TypeFilter(typeof(CustomAllActionResultFilterAttribute))]public IActionRe…

67.WEB渗透测试-信息收集- WAF、框架组件识别(7)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;66.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;6&#xff09;-CSDN博客 关于w…

【大模型】MOE模型混合专家调度机制详解

MOE模型混合专家调度机制详解 引言 在大规模机器学习和深度学习应用中&#xff0c;模型的复杂性和计算需求日益增长。为了解决单个专家模型在特定任务上的局限性&#xff0c;Mixture of Experts (MoE) 架构应运而生。MoE模型通过组合多个专家模型&#xff0c;能够在保持高效率…

第四届数字安全大会:AI时代数据安全策略与天空卫士创新实践

2024年6月22日&#xff0c;以 “新质•真能力”为主题的第四届数字安全大会在北京隆重召开。这场由数世咨询和CIO时代联合主办的行业盛会&#xff0c;集中探讨了大模型、数据治理与流通、以及安全运营等当前最前沿的议题。大会吸引了来自不同行业的首席信息官&#xff08;CIO&a…

2024Datawhale-AI夏令营——机器学习挑战赛——学习笔记

#ai夏令营#datawhale#夏令营 Day1:入门级demo运行 这个其实比较简单&#xff0c;按照操作来做就行了&#xff0c;特征工程和调参暂时都没有做&#xff0c;后续的才是重头戏。 Day2:正式比赛开始 赛题&#xff1a;数据挖掘赛道——利用机器学习方法根据给定的特征判断PROTACs…

【EFK】efk 8收集docker容器日志测试

前言 目前&#xff0c;efk 全家桶已经更新到版本8 了&#xff0c;本章节我们使用8版本的elk搭建日志收集系统&#xff0c;了解它的配置运行过程&#xff0c;方便以后在更复杂的环境中更好的使用。 版本默认就是8最新的&#xff0c;也可以自己指定其他8的版本 elasticsearch: …

左耳听风_008_07_推荐阅读每个程序员都该知道的知识

你好&#xff0c;我是陈浩网名左耳朵耗子。 在整个为期一年的专栏内容中啊&#xff0c;我会一步步向你推荐一些有价值的内容供你参考。 这些内容有中文&#xff0c;有英文&#xff0c;也有视频。 他们都是我认为对我非常有价值的信息&#xff0c;我也希望他们能够对你有同样…

vs 远程链接ssh 开发 简单实验

1.概要 动态编译语言&#xff0c;跨平台必须做分别的编译&#xff0c;比如linux和windows。如何再windows环境下开发编译出linux平台的程序呢&#xff0c;vs支持远程链接编辑&#xff0c;就是再vs中写代码&#xff0c;但是编译确是链接远程的环境编译的。 2.环境准备 2.1 vs…

R语言学习,入门

我是一名6年开发经验的程序员&#xff0c;后端&#xff0c;大数据&#xff0c;前端都会。 现在加入了医疗行业&#xff0c;要做数据分析&#xff0c;前同事的实验室生信专业的&#xff0c;用的是R语言&#xff0c;为了跑通他的程序。就来学一下吧&#xff0c;看了一下好像挺简…

代码随想录day38 动态规划(4)

1049. 最后一块石头的重量 II - 力扣&#xff08;LeetCode&#xff09; 难点在于将此问题转为0-1背包问题。思路是将石头分为重量尽可能接近的两堆&#xff0c;两堆之间对碰&#xff0c;到最后剩下的重量会最小。解法与分割等和子集类似。易错点是遍历target时从后往前。 cl…

关于软件本地化,您应该了解什么?

软件本地化是调整软件应用程序以满足目标市场的语言、文化和技术要求的过程。它不仅仅涉及翻译用户界面&#xff1b;它包含一系列活动&#xff0c;以确保软件在目标语言环境中可用且相关。以下是您应该了解的有关软件本地化的一些关键方面&#xff1a; 了解范围 软件本地化是…

0704模拟记录

1.完美数 暴力 #include <iostream> #include <vector>using namespace std;bool perfect(long long res) {if (res < 10) {return true;}else if (res > 10 && res < 100 && res % 10 0) {return true;}else if (res > 100 &&…

华为机试HJ12字符串反转

华为机试HJ12字符串反转 题目&#xff1a; 接受一个只包含小写字母的字符串&#xff0c;然后输出该字符串反转后的字符串。&#xff08;字符串长度不超过1000&#xff09; 想法&#xff1a; 针对输入字符串从后往前遍历&#xff0c;输出反转字符串 input_str input()resu…

requets.GET.get()怎样使用?

request.GET.get()是Django中用于获取GET请求参数的方法。 使用方法如下&#xff1a; 在视图函数中引入HttpRequest模块&#xff1a;from django.http import HttpRequest在视图函数中使用request.GET.get()方法获取GET请求参数&#xff0c;参数为需要获取的参数名 def my_…

水利水电安全员C证考试题库资料,2024年全国考试通用!

1.安全生产民事责任&#xff0c;是指责任主体违反安全生产法律规定造成&#xff08;&#xff09;&#xff0c;由人民法院依照民事法律强制其行使民事赔偿的一种法律责任。民事责任追究的目的是为了最大限度的维护当事人受到民事损害时享有获得民事赔偿的权利。 A.民事损伤 B.…

针对SVN、GIT版本管理工具进行源代码加密保护

针对SVN、GIT版本管理工具进行源代码加密保护 在软件开发过程中&#xff0c;版本管理工具如SVN和GIT是不可或缺的组成部分&#xff0c;它们帮助团队管理源代码的变更和版本。然而&#xff0c;这些工具也面临着源代码泄露的安全风险。如果不针对数据进行加密保护&#xff0c;很…

如何从腾讯云迁移到AWS

随着跨境出海潮不断扩大&#xff0c;企业越来越意识到将工作负载迁移到海外节点的必要性&#xff0c;以获取更多功能、灵活性和性能。然而&#xff0c;顺利迁移业务主机并确保业务稳定访问是一项具有挑战性的任务。在此挑战中&#xff0c;借助AWS迁移工具和迁移流程的强大支持&…

003 线程的暂停和中断

文章目录 暂停中断**阻塞情况下中断&#xff0c;抛出异常后线程恢复非中断状态&#xff0c;即 interrupted false**调用Thread.interrupted() 方法后线程恢复非中断状态 暂停 Java中线程的暂停是调用 java.lang.Thread 类的 sleep 方法。该方法会使当前正在执行的线程暂停指定…

如何检查购买的Facebook账号优劣?

Facebook 是全球最受欢迎的社交网络之一,为品牌广告提供了巨大的潜力。许多公司和营销人员使用 Facebook 来推广他们的产品和服务&#xff0c;经常会购买账号。当然也分出了很多账号&#xff0c;比如个人号&#xff0c;BM号&#xff0c;广告号&#xff0c;小黑号等等。 但是,有…