• 屏障


    屏障

    关卡是一个用户定义的同步基元,它使多个线程(称为“参与者”)可以分阶段同时参与执行一个算法。 每个参与者将执行到代码中的关卡点为止。 关卡表示一个阶段的工作结束。 当某个参与者到达关卡时,它将阻塞,直至所有参与者都已到达同一关卡为止。 在所有参与者都已到达关卡之后,您可以选择调用后期阶段操作。 在所有其他线程仍被阻塞时,单个线程可以使用此后期阶段操作来执行操作。 在执行该操作之后,所有参与者都将被取消阻塞。

    添加和删除参与者

    创建 Barrier 时,指定参与者的数量。 也可在任何时间动态地添加或移除参与者

    出现故障的关卡

    如果一个参与者未能到达关卡,则会发生死锁。 若要避免这些死锁,请使用 SignalAndWait 方法的重载来指定超时期限和取消标记。 这些重载将返回一个布尔值,每个参与者都会在它继续下一阶段之前检查该值。

    后期阶段异常

    如果后期阶段委托引发异常,则在 BarrierPostPhaseException 对象中包装它,然后将其传播到所有参与者。

    关卡与ContinueWhenAll

    当线程循环执行多个阶段时,关卡尤其有用。 如果您的代码只需要一个或两个阶段的工作,请考虑是否使用带有各种隐式联接的 System.Threading.Tasks.Task 对象

    一个Demo:

    using System;
    using System.Text;
    using System.Threading;
    
    namespace MyConsole2
    {
        class Program
        {
    
            static string[] words1 = new string[] { "brown", "jumped", "the", "fox", "quick" };
            static string[] words2 = new string[] { "dog", "lazy", "the", "over" };
            static string solution = "the quick brown fox jumped over the lazy dog.";
    
            static bool success = false;
    
            static Barrier barrier = new Barrier(1, //参与线程的数量
                b =>  // 要在每个阶段后执行的操作。 可以传递 null
                {
                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);
                Console.WriteLine("thread ID:"+Thread.CurrentThread.ManagedThreadId);
                if (String.CompareOrdinal(solution, sb.ToString()) == 0)
                {
                    success = true;
                    Console.WriteLine("
    The solution was found in {0} attempts", barrier.CurrentPhaseNumber); Console.WriteLine();
                }
            });
    
            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;
                    }
                    //等待其它参与者到达
                    barrier.SignalAndWait();
                }
            }
            static void Main(string[] args)
            {
                Thread t1 = new Thread(() => Solve(words1));
                Thread t2 = new Thread(() => Solve(words2));
                barrier.AddParticipant();//添加一个参与者
                t1.Start();
                t2.Start();
    
                Console.ReadLine();
            }
    
             
    
        }
    

    }

  • 相关阅读:
    分布式系统的架构思路
    可汗学院超经典、超实用概率论总结——商女不知忘国恨,隔江犹看概率论
    傅里叶分析之掐死教程(完整版)
    谈谈敏捷开发
    C# 读xml注释或过滤xml注释
    CTF中那些脑洞大开的编码和加密
    C#关闭一个窗口的同时打开另一个窗口
    继《关于讯飞语音SDK开发学习》之打包过程中遇到小问题
    使用ffmpeg录音
    leetcode 1. Two Sum
  • 原文地址:https://www.cnblogs.com/goodlucklzq/p/4487943.html
Copyright © 2020-2023  润新知