文盘Rust -- Mutex解决并发写文件乱序问题 | 京东云技术团队
在实际开发过程中,我们可能会遇到并发写文件的场景,如果处理不当很可能出现文件内容乱序问题。下面我们通过一个示例程序描述这一过程并给出解决该问题的方法。
use std::{ fs::{self, File, OpenOptions}, io::{Write}, sync::Arc, time::{SystemTime, UNIX_EPOCH}, }; use tokio::task::JoinSet; fn main() { println!("parallel write file!"); let max_tasks = 200; let _ = fs::remove_file("/tmp/parallel"); let file_ref = OpenOptions::new() .create(true) .write(true) .append(true) .open("/tmp/parallel") .unwrap(); let mut set: JoinSet<()> = JoinSet::new(); let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { loop { while set.len() >= max_tasks { set.join_next().await; } 未做写互斥函数 let mut file_ref = OpenOptions::new() .create(true) .write(true) .append(true) .open("/tmp/parallel") .unwrap(); set.spawn(async move { write_line(&mut file_ref) }); } }); } fn write_line(file: &mut File) { for i in 0..1000 { let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); let mut content = now.as_secs().to_string(); content.push_str("_"); content.push_str(&i.to_string()); file.write_all(content.as_bytes()).unwrap(); file.write_all("\n".as_bytes()).unwrap(); file.write_all("\n".as_bytes()).unwrap(); } }
代码不复杂,tokio 实现一个并发runtime,写文件函数是直接写时间戳,为了方便展示乱序所以写入两次换行。
输出的文本大概长这样
1691287258_979 1691287258_7931691287258_301 1691287258_7431691287258_603 1691287258_8941691287258_47 1691287258_895 1691287258_553 1691287258_950 1691287258_980 1691287258_48 1691287258_302 1691287258_896 1691287258_744 1691287258_6041691287258_554
很明显,写入并未达到预期,间隔并不平均,函数内部的执行步骤是乱序的。
我们把上面的程序改造一下
use std::{ fs::{self, File, OpenOptions}, io::Write, sync::Arc, time::{SystemTime, UNIX_EPOCH}, }; use tokio::sync::Mutex; use tokio::task::JoinSet; fn main() { println!("parallel write file!"); let max_tasks = 200; let _ = fs::remove_file("/tmp/parallel"); let file_ref = OpenOptions::new() .create(true) .write(true) .append(true) .open("/tmp/parallel") .unwrap(); let f = Arc::new(Mutex::new(file_ref)); let mut set: JoinSet<()> = JoinSet::new(); let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { loop { while set.len() >= max_tasks { set.join_next().await; } let mut file = Arc::clone(&f); set.spawn(async move { write_line_mutex(&mut file).await }); } }); } async fn write_line_mutex(mutex_file: &Arc<Mutex<File>>) { for i in 0..1000 { let mut f = mutex_file.lock().await; let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); let mut content = now.as_secs().to_string(); content.push_str("_"); content.push_str(&i.to_string()); f.write_all(content.as_bytes()).unwrap(); f.write_all("\n".as_bytes()).unwrap(); f.write_all("\n".as_bytes()).unwrap(); } }
这次我们用到了tokio::sync::Mutex,write_line_mutex函数在每次执行写任务以前先获取文件互斥锁。
看看这次的文件内容
1691288040_374 1691288040_374 1691288040_374 1691288040_375 1691288040_374 1691288040_374 1691288040_374 1691288040_374 1691288040_374 1691288040_374 1691288040_374 1691288040_374 1691288040_374 1691288040_374 1691288040_375 1691288040_375 1691288040_374 1691288040_375 1691288040_375 1691288040_375 1691288040_375 1691288040_375 1691288040_375 1691288040_375 1691288040_375 1691288040_375 1691288040_375
写入的格式正确,保证每次函数写函数完整执行。
关于文件写互斥这点事儿,今儿就聊到这。
作者:京东科技 贾世闻
来源:京东云开发者社区
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Hutool:一行代码搞定数据脱敏 | 京东云技术团队
1. 什么是数据脱敏 1.1 数据脱敏的定义 数据脱敏百度百科中是这样定义的: 数据脱敏,指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。这样就可以在开发、测试和其它非生产环境以及外包环境中安全地使用脱敏后的真实数据集。在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供测试使用,如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏。是数据库安全技术之一。 总的来说,数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。 在数据脱敏过程中,通常会采用不同的算法和技术,以根据不同的需求和场景对数据进行处理。例如,对于身份证号码,可以使用掩码算法(masking)将前几位数字保留,其他位用“X”或"*"代替;对于姓名,可以使用伪造(pseudonymization)算法,将真实姓名替换成随机生成的假名。 1.2 常用脱敏规则 替换、重排、加密、截断、掩码 2. Hutool工具介绍 2.1 引入Maven配置 在项目的pom.xml的dependencies中加入以下内容,这里以5.8...
- 下一篇
一文详解自然语言处理两大任务与代码实战:NLU与NLG
自然语言处理(NLP)涵盖了从基础理论到实际应用的广泛领域,本文深入探讨了NLP的关键概念,包括词向量、文本预处理、自然语言理解与生成、统计与规则驱动方法等,为读者提供了全面而深入的视角。 作者 TechLead,拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人 1. 自然语言处理定义 自然语言处理(NLP)是一门交叉学科领域,涵盖了计算机科学、人工智能、语言学等多个学科。它旨在使计算机能够理解、解释和生成人类语言的方式,从而创建与人类之间的自然、无缝的交互。 NLP的定义和重要性 自然语言处理的主要任务是让计算机能够像人类一样理解和生成自然语言。它能够让机器读懂人类的语言,使得人们与计算机的交互更加自然流畅。这不仅可以大大提高人机交互的效率,而且也为许多行业如客服、医疗、教育等提供了极大的便利。 NLP的主要挑战 歧义解析:自然语言充满了歧义,同一句话在不同的上下文中可能有完全不同的含义。 语法复杂性:不同的语言有各自复杂的语法规则,理解这些规则并将其转化为机器可理...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS8安装Docker,最新的服务器搭配容器使用
- Hadoop3单机部署,实现最简伪集群
- MySQL8.0.19开启GTID主从同步CentOS8
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8编译安装MySQL8.0.19
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境