Rust std::sync::Barrier 栅栏详解1、 引言2、 Barrier 是什么2.1、 核心概念2.2 、与其它同步原语的区别3、Barrier 的基本用法3.1、 创建 Barrier3.2、 等待到达4、 wait() 的返回值5、 Barrier 的复用6、 实战示例并行计算求和7、注意事项与常见陷阱7.1、 参与者数量必须匹配7.2、 线程 panic 会导致死锁7.3、 不要在线程池中滥用7.4、 与 Condvar 的区别8、总结二、示例代码1、 引言在多线程编程中线程之间的同步是一个核心问题。Rust 标准库提供了多种同步原语如Mutex、RwLock、Condvar等而std::sync::Barrier栅栏则是其中一种非常实用但常被忽视的同步工具。Barrier允许一组线程相互等待直到所有线程都到达某个执行点后再一起继续往下执行。这种「会合点」机制在并行计算、分阶段任务处理等场景中非常有用。本文将深入剖析Barrier的原理、用法、注意事项并通过多个实战示例帮助你彻底掌握它。2、 Barrier 是什么Barrier是 Rust 标准库提供的一种同步原语用于让多个线程在某个执行点相互等待直到所有参与的线程都到达该点后才一起放行继续执行。2.1、 核心概念参与者Party参与同步的线程数量在创建Barrier时指定。到达Arrive线程调用wait()方法表示自己已到达栅栏点。放行Release当最后一个参与者到达后所有等待的线程被同时唤醒一起继续执行。2.2 、与其它同步原语的区别同步原语作用典型场景Mutex互斥访问共享数据保护临界区Condvar条件等待与唤醒生产者-消费者Barrier多线程会合同步分阶段并行计算Mutex和Condvar解决的是「数据竞争」和「条件等待」问题而Barrier解决的是「多线程步调一致」的问题。3、Barrier 的基本用法3.1、 创建 Barrier使用Barrier::new(n)创建一个需要n个参与者到达的栅栏usestd::sync::Barrier;// 创建一个需要 3 个线程到达的栅栏letbarrierBarrier::new(3);3.2、 等待到达线程调用wait()方法表示自己已到达栅栏点usestd::sync::{Arc,Barrier};usestd::thread;fnmain(){letbarrierArc::new(Barrier::new(3));letmuthandlesvec![];foriin0..3{letbarrierArc::clone(barrier);lethandlethread::spawn(move||{println!(线程 {} 开始工作,i);thread::sleep(std::time::Duration::from_millis(i*100));// 到达栅栏等待其它线程barrier.wait();println!(线程 {} 通过栅栏继续执行,i);});handles.push(handle);}forhandleinhandles{handle.join().unwrap();}}运行结果顺序可能略有不同线程 0 开始工作 线程 1 开始工作 线程 2 开始工作 线程 2 通过栅栏继续执行 线程 0 通过栅栏继续执行 线程 1 通过栅栏继续执行可以看到三个线程各自完成「开始工作」后都在栅栏处等待直到最后一个线程到达后才一起继续执行。4、 wait() 的返回值Barrier::wait()返回一个BarrierWaitResult它有一个is_leader()方法用于判断当前线程是否是「领导者」——即最后一个到达栅栏的线程usestd::sync::{Arc,Barrier};usestd::thread;fnmain(){letbarrierArc::new(Barrier::new(3));letmuthandlesvec![];foriin0..3{letbarrierArc::clone(barrier);lethandlethread::spawn(move||{letresultbarrier.wait();ifresult.is_leader(){println!(线程 {} 是最后一个到达的领导者,i);}else{println!(线程 {} 不是领导者,i);}});handles.push(handle);}forhandleinhandles{handle.join().unwrap();}}输出结果线程 2 是最后一个到达的领导者 线程 0 不是领导者 线程 1 不是领导者is_leader()在需要「由某个线程执行一次性的初始化/汇总工作」时非常有用例如分阶段计算中由领导者汇总各线程的结果。5、 Barrier 的复用Barrier的一个重要特性是可复用。当所有线程通过栅栏后Barrier会自动重置可以继续用于下一轮同步。这使得它非常适合分阶段多轮并行任务usestd::sync::{Arc,Barrier};usestd::thread;fnmain(){letbarrierArc::new(Barrier::new(3));letrounds3;letmuthandlesvec![];foriin0..3{letbarrierArc::clone(barrier);lethandlethread::spawn(move||{forroundin0..rounds{// 模拟阶段工作println!(线程 {} 执行第 {} 轮工作,i,round);thread::sleep(std::time::Duration::from_millis(50));// 等待所有线程完成本轮barrier.wait();}});handles.push(handle);}forhandleinhandles{handle.join().unwrap();}}输出结果线程 0 执行第 0 轮工作 线程 1 执行第 0 轮工作 线程 2 执行第 0 轮工作 线程 0 执行第 1 轮工作 线程 1 执行第 1 轮工作 线程 2 执行第 1 轮工作 线程 0 执行第 2 轮工作 线程 1 执行第 2 轮工作 线程 2 执行第 2 轮工作可以看到每一轮中所有线程都完成工作后才会统一进入下一轮。这正是Barrier复用的典型场景。6、 实战示例并行计算求和下面通过一个完整的实战示例展示Barrier在并行计算中的应用——多个线程分别计算部分和最后汇总usestd::sync::{Arc,Barrier,Mutex};usestd::thread;fnmain(){letdata:Veci32(1..100).collect();letnum_threads4;letchunk_sizedata.len()/num_threads;letbarrierArc::new(Barrier::new(num_threads));letpartial_sumsArc::new(Mutex::new(vec![0i32;num_threads]));letmuthandlesvec![];fortin0..num_threads{letdatadata.clone();letbarrierArc::clone(barrier);letpartial_sumsArc::clone(partial_sums);lethandlethread::spawn(move||{letstartt*chunk_size;letendiftnum_threads-1{data.len()}else{(t1)*chunk_size};letsum:i32data[start..end].iter().sum();// 写入部分和letmutsumspartial_sums.lock().unwrap();sums[t]sum;drop(sums);// 等待所有线程完成部分计算letresultbarrier.wait();// 由领导者汇总ifresult.is_leader(){letsumspartial_sums.lock().unwrap();lettotal:i32sums.iter().sum();println!(总和 {},total);}});handles.push(handle);}forhandleinhandles{handle.join().unwrap();}}输出结果总和 5050在这个示例中Barrier确保了所有线程都完成部分和计算后才由领导者线程统一汇总避免了汇总过早执行导致的结果不完整问题。7、注意事项与常见陷阱7.1、 参与者数量必须匹配Barrier::new(n)中的n必须与实际调用wait()的线程数量一致。如果某个线程提前退出或未调用wait()其它线程将永远阻塞// 错误示例创建了 3 个参与者的栅栏但只有 2 个线程调用 wait()letbarrierArc::new(Barrier::new(3));// 只有 2 个线程调用 barrier.wait()第 3 个永远不会到达// 结果两个线程永久阻塞7.2、 线程 panic 会导致死锁如果某个线程在调用wait()之前 panic 退出其它线程将永远等待letbarrierArc::new(Barrier::new(3));// 某个线程 panic 了thread::spawn(move||{panic!(出错了);// barrier.wait() 永远不会执行});7.3、 不要在线程池中滥用在线程池场景中线程数量是动态的使用Barrier需要格外小心确保每次参与同步的线程数量与Barrier的参与者数量一致。7.4、 与 Condvar 的区别Barrier和Condvar都能实现线程等待但语义不同Barrier所有线程互相等待直到全部到达。Condvar线程等待某个条件成立由其它线程主动通知。8、总结std::sync::Barrier是 Rust 标准库中一个简洁而强大的同步原语核心要点如下会合机制让一组线程在指定执行点相互等待全部到达后一起放行。可复用通过栅栏后自动重置适合多轮分阶段任务。领导者识别通过wait()返回的BarrierWaitResult::is_leader()识别最后一个到达的线程用于执行汇总等一次性工作。适用场景并行计算的分阶段同步、多线程任务的对齐、分布式计算的本地会合等。掌握Barrier你就能在多线程编程中更好地控制线程的执行节奏写出更健壮的并发代码。二、示例代码usestd::sync::{Arc,Barrier};usestd::thread;usestd::time::Duration;fnmain(){constTHREAD_COUNT:usize4;// 创建栅栏等待4个线程全部到达才放行letbarrierArc::new(Barrier::new(THREAD_COUNT));letmuthandlesVec::with_capacity(THREAD_COUNT);forthread_idin0..THREAD_COUNT{letbArc::clone(barrier);leththread::spawn(move||{// 第一轮栅栏同步 println!([线程{}] 执行前置任务准备等待栅栏(第1轮),thread_id);// 模拟每个线程耗时不等的前置工作thread::sleep(Duration::from_millis((thread_idasu64)*200));// 到达栅栏点阻塞等待letres1b.wait();// is_leader()仅有一个线程拿到trueifres1.is_leader(){println!([线程{} LEADER ] 第一轮全部线程就绪统一放行,thread_id);}else{println!([线程{}] 栅栏放行开始执行第一轮后续逻辑,thread_id);}// 第二轮栅栏同步Barrier可重复使用 thread::sleep(Duration::from_millis(100));println!([线程{}] 完成第一轮业务等待第二轮栅栏,thread_id);letres2b.wait();ifres2.is_leader(){println!([线程{} LEADER ] 第二轮全部线程就绪统一放行,thread_id);}else{println!([线程{}] 第二轮栅栏放行,thread_id);}format!(线程{} 执行完成,thread_id)});handles.push(h);}// 等待所有子线程结束forhinhandles{letreth.join().unwrap();println!({},ret);}println!(全部线程执行完毕);}PSE:\leaning\slint\testcargo runRunningtarget\debug\ftp-client.exe[线程0]执行前置任务准备等待栅栏(第1轮)[线程1]执行前置任务准备等待栅栏(第1轮)[线程2]执行前置任务准备等待栅栏(第1轮)[线程3]执行前置任务准备等待栅栏(第1轮)[线程3LEADER]第一轮全部线程就绪统一放行[线程1]栅栏放行开始执行第一轮后续逻辑[线程2]栅栏放行开始执行第一轮后续逻辑[线程0]栅栏放行开始执行第一轮后续逻辑[线程0]完成第一轮业务等待第二轮栅栏[线程2]完成第一轮业务等待第二轮栅栏[线程3]完成第一轮业务等待第二轮栅栏[线程1]完成第一轮业务等待第二轮栅栏[线程1LEADER]第二轮全部线程就绪统一放行[线程3]第二轮栅栏放行[线程0]第二轮栅栏放行[线程2]第二轮栅栏放行 线程0执行完成 线程1执行完成 线程2执行完成 线程3执行完成 全部线程执行完毕PSE:\leaning\slint\test
企业数字化 ERP 产品动态
相关推荐
嵌入式分享#47:为什么 eDP 屏会概率性不显示?(RK3568) 嵌入式分#47:为什么 eDP 屏会概率性不示?(RK3568)摘要:RK3568 调试 eDP 时,屏幕发无法点亮,日显示 Link Training 失败。文分析 eDP Training 的作用并给出在 U-Boot 阶段重复训练的临时修复方案… · 2026/9/27 11:29:55
数字物业安全监测系统详解:从传感器接入到云平台告警闭环 凌晨两点,地下车库积水越过警戒线,水泵却因为控制柜接触器卡死没有启动,值班室电话被打到爆——搞过物业弱电的人应该都见过这种场景。传统靠人工巡检、电话上报的模式,在夜间和恶劣天气下几乎等于裸奔。要系统性地解决这类问题&a… · 2026/9/27 11:29:31
传感器+RTU+云平台,数字物业安全监测闭环实战指南 物业安全监测一旦数字化,传感器、RTU网关和云平台就组成了一个绕不开的闭环。这里说的不是演示台架,而是24小时跑在园区、写字楼和住宅小区里的工程系统。我做过几个数字物业改造项目,最大的感受是:很多人认识传感器,也… · 2026/9/27 11:29:31
Trae AI IDEA安装与使用:TaoToken统一Key接入与settings.json配置骨架 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 14:36:18
做网站会员登陆图解步骤:3步搞定高转化入口 做网站会员登陆图解步骤:3步搞定高转化入口 别再盯着那些千篇一律的模板网站看了。说实话,大多数企业官网的会员登录入口,要么藏在页脚角落没人点,要么设计得像个二维码广告,丑得让人不想点。很多老板觉得,网站嘛,能看就行,会员系统那是大公司才玩的… · 2026/9/27 14:36:18
网站开发如何收费?拆透建站报价单里的猫腻 网站开发如何收费?拆透建站报价单里的猫腻 域名服务器搞不懂,是不是让你在看建站报价单时心里直打鼓?别急,这行水太深,很多小白刚接触就被各种名词绕晕,生怕被坑。今天咱就掰开了揉碎了,把【网站开发如何收费】这件事讲得明明白白,让你拿到【建站报价… · 2026/9/27 14:36:06
2025年8月国产大模型综合评测:5大维度TOP10榜单与TaoToken接入配置指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 14:36:06
DeepSeek DualPath框架实战:让推理性能翻倍的配置与验证 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 14:35:41
百度推广的价格表对比评测 百度推广价格表揭秘:新手入门避坑指南 自己不会代码想做网站,却卡在“百度推广的价格表”这个环节,是不是觉得一头雾水?很多新手入门的第一反应是去官网看报价,但实际充值后才发现,钱花得没道理,流量没预期。这不仅是技术门槛,更是信息差造成的成本黑… · 2026/9/27 14:35:29
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01