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

写在前面

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

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

关键代码如下:

barrier.SignalAndWait()

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

代码实现

cs 复制代码
//#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 TRACE
            System.Diagnostics.Trace.WriteLine(sb.ToString());
#endif
            Console.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();
            }
        }
    }
}

调用示例

相关推荐
大飞pkz1 小时前
【设计模式】题目小练2
开发语言·设计模式·c#·题目小练
csdn_aspnet3 小时前
MongoDB C# .NetCore 驱动程序 序列化忽略属性
mongodb·c#·.netcore
浪扼飞舟4 小时前
c#基础二(类和对象,构造器调用顺序、访问级别、重写和多态、抽象类和接口)
java·开发语言·c#
好望角雾眠7 小时前
第四阶段C#通讯开发-1:通讯基础理论,串口,通讯模式,单位转换,代码示例
开发语言·笔记·c#·串口·通讯
薄荷撞~可乐14 小时前
C#Task(Api)应用
开发语言·c#
almighty2719 小时前
C#WPF控制USB摄像头参数:曝光、白平衡等高级设置完全指南
开发语言·c#·wpf·usb相机·参数设置
后青春期的诗go20 小时前
金蝶云星空插件开发记录(一)
c#·钉钉·金蝶云星空·插件开发
大飞pkz1 天前
【设计模式】题目小练1
开发语言·设计模式·c#·题目小练
lljss20201 天前
C# 每个chartArea显示最小值、平均值、最大值
开发语言·c#
wearegogog1231 天前
C#与Twincat 2 实现上位机控制软PLC功能
开发语言·c#