当前位置: 首页 > news >正文

C# 使用屏障来使多线程并发操作保持同步

写在前面

以下是微软官方对屏障类的介绍,System.Threading.Barrier 可用来作为实现并发同步操作的基本单元,让多个线程(参与者)分阶段并行处理目标算法。在达到代码中的屏障点之前,每个参与者将继续执行,屏障表示工作阶段的末尾;单个参与者到达屏障后将被阻止,直至所有参与者都已达到同一障碍。 所有参与者都已达到屏障后,你可以选择调用阶段后操作。 此阶段后操作可由单线程用于执行操作,而所有其他线程仍被阻止。执行此操作后,所有参与者将不受阻止,继续执行直到满足退出条件。

下面的程序用于统计两个线程使用随机算法重新随机选择字词,分别在同一阶段查找一半解决方案时所需的迭代次数(或阶段数)。在每个线程随机选择字词后,屏障后阶段操作会比较两个结果,以确定整个句子是否按正确的字词顺序呈现。

关键代码如下:

barrier.SignalAndWait()

 设置了代码屏障点,代码运行到这里会等待所有参与的线程都执行完之前的代码。

代码实现

//#define TRACE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace BarrierSimple
{class Program{static string[] words1 = new string[] { "brown", "jumps", "the", "fox", "quick" };static string[] words2 = new string[] { "dog", "lazy", "the", "over" };static string solution = "the quick brown fox jumps over the lazy dog.";static bool success = false;static Barrier barrier = new Barrier(2, (b) =>{StringBuilder sb = new StringBuilder();for (int i = 0; i < words1.Length; i++){sb.Append(words1[i]);sb.Append(" ");}for (int i = 0; i < words2.Length; i++){sb.Append(words2[i]);if (i < words2.Length - 1)sb.Append(" ");}sb.Append(".");
#if TRACESystem.Diagnostics.Trace.WriteLine(sb.ToString());
#endifConsole.CursorLeft = 0;Console.Write("Current phase: {0}", barrier.CurrentPhaseNumber);if (String.CompareOrdinal(solution, sb.ToString()) == 0){success = true;Console.WriteLine("\r\nThe solution was found in {0} attempts", barrier.CurrentPhaseNumber);}});static void Main(string[] args){Thread t1 = new Thread(() => Solve(words1));Thread t2 = new Thread(() => Solve(words2));t1.Start();t2.Start();// Keep the console window open.Console.ReadLine();}// Use Knuth-Fisher-Yates shuffle to randomly reorder each array.// For simplicity, we require that both wordArrays be solved in the same phase.// Success of right or left side only is not stored and does not count.static void Solve(string[] wordArray){while (success == false){Random random = new Random();for (int i = wordArray.Length - 1; i > 0; i--){int swapIndex = random.Next(i + 1);string temp = wordArray[i];wordArray[i] = wordArray[swapIndex];wordArray[swapIndex] = temp;}// We need to stop here to examine results// of all thread activity. This is done in the post-phase// delegate that is defined in the Barrier constructor.barrier.SignalAndWait();}}}
}

调用示例

相关文章:

  • AcWing:4646. 爬树的甲壳虫
  • mysql INSERT数据覆盖现有元素(若存在)
  • 【MQ01】什么是消息队列?用哪个消息队列?
  • Go语言学习笔记:基础语法和类型
  • 【Java】SpringMVC参数接收
  • 【电商API接口Python实例】100个Python爬虫实例
  • pyspark之Structured Streaming file文件案例1
  • 设备通过GB28181注册到EasyCVR,平台看不到设备信息的排查方法汇总
  • OpenCV第 2 课 OpenCV 环境搭建
  • LabVIEW高级CAN通信系统
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • 深入Android S (12.0) 探索Framework之输入子系统InputReader的流程
  • notepad++: 插件fingertext 来创建代码块
  • 考研过后你如坐针毡,而有些人因选择中国人民大学与加拿大女王大学金融硕士而乐在其中
  • 网络中黑客攻击使用手段Top25漏洞常见参数,8个WAF绕过,一些用于查找敏感文件的语法
  • 【Linux系统编程】快速查找errno错误码信息
  • 【技术性】Search知识
  • 4. 路由到控制器 - Laravel从零开始教程
  • Bytom交易说明(账户管理模式)
  • Fabric架构演变之路
  • gulp 教程
  • Java IO学习笔记一
  • JS基础之数据类型、对象、原型、原型链、继承
  • js写一个简单的选项卡
  • JWT究竟是什么呢?
  • laravel5.5 视图共享数据
  • React-flux杂记
  • spring学习第二天
  • 不上全站https的网站你们就等着被恶心死吧
  • 从setTimeout-setInterval看JS线程
  • 大型网站性能监测、分析与优化常见问题QA
  • 汉诺塔算法
  • 那些年我们用过的显示性能指标
  • 前端之Sass/Scss实战笔记
  • 找一份好的前端工作,起点很重要
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • ​secrets --- 生成管理密码的安全随机数​
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #Java第九次作业--输入输出流和文件操作
  • #Spring-boot高级
  • #控制台大学课堂点名问题_课堂随机点名
  • (1)常见O(n^2)排序算法解析
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (三)c52学习之旅-点亮LED灯
  • (十一)图像的罗伯特梯度锐化
  • (实战篇)如何缓存数据
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .net访问oracle数据库性能问题
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • /etc/fstab 只读无法修改的解决办法