zoukankan      html  css  js  c++  java
  • Barrier Class Usage(Synchronization of .net 4.0)

    The Barrier class is a signaling construct new to Framework 4.0. It implements a thread execution barrier, which allows many threads to rendezvous at a point in time. The class is very fast and efficient, and is built upon Wait, Pulse, and spinlocks.

    To use this class:

    1. Instantiate it, specifying how many threads should partake in the rendezvous (you can change this later by calling AddParticipants/RemoveParticipants).
    2. Have each thread call SignalAndWait when it wants to rendezvous.

    Instantiating Barrier with a value of 3 causes SignalAndWait to block until that method has been called three times. But unlike a CountdownEvent, it then automatically starts over: calling SignalAndWait again blocks until called another three times. This allows you to keep several threads “in step” with each other as they process a series of tasks.

     

    In the following example, each of three threads writes the numbers 0 through 4, while keeping in step with the other threads:

    static Barrier _barrier = new Barrier (3);   
    static void Main() {   
    new Thread (Speak).Start();   
    new Thread (Speak).Start();   
    new Thread (Speak).Start(); }   
    static void Speak() {   
    for (int i = 0; i < 5; i++)   
    {     Console.Write (i + " ");    
    _barrier.SignalAndWait();   } } 
    0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 

    A really useful feature of Barrier is that you can also specify a post-phase action when constructing it. This is a delegate that runs after SignalAndWait has been called n times, but before the threads are unblocked. In our example, if we instantiate our barrier as follows:

    static Barrier _barrier = new Barrier (3, barrier => Console.WriteLine()); 

    then the output is:

    0 0 0  
    1 1 1  
    2 2 2  
    3 3 3  
    4 4 4  

    A post-phase action can be useful for coalescing data from each of the worker threads. It doesn’t have to worry about preemption, because all workers are blocked while it does its thing. 

    Another way of Explaination

    Visual Studio 2010 and .NET Framework 4 Training Kit中有个System.Threading.Barrier的Demo,通过Barrier Class我们可以控制线程的运行,做到线程同步的效果。

    Barrier Class在使用上十分的简单,只要在Barrier的构造函数中传入participantCount(简单的说就是要等待的线程个数),并在要同步的点调用SignalAndWait方法就可以了。线程会在调用SignalAndWait之后暂停运行,等待所有参与的线程都到达了同步点才继续往下运行。 

     

    举个例子来看,假设今天Charlie、Mac、Dennis三个人相约要去西雅图喝咖啡。由于三个人的住的地区不尽相同,且车子都需要加油,因此他们约在途中会经过的加油站待会合后一同前往。这样的情境我们可以通过Thread与Barrier用程序仿真出来。

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Threading;

    namespace BarrierDemo 

        class Program 
        { 
            static Barrier sync; 
            static CancellationToken token;

            static void Main(string[] args) 
            { 
                var source = new CancellationTokenSource(); 
                token = source.Token; 
                sync = new Barrier(3);

                var charlie = new Thread(() => DriveToBoston("Charlie", TimeSpan.FromSeconds(1))); charlie.Start(); 
                var mac = new Thread(() => DriveToBoston("Mac", TimeSpan.FromSeconds(2))); mac.Start(); 
                var dennis = new Thread(() => DriveToBoston("Dennis", TimeSpan.FromSeconds(3))); dennis.Start();

                //source.Cancel();

                charlie.Join(); 
                mac.Join(); 
                dennis.Join();

                Console.ReadKey(); 
            }

            static void DriveToBoston(string name, TimeSpan timeToGasStation) 
            { 
                try 
                { 
                    Console.WriteLine("[{0}] Leaving House", name);

                    // Perform some work 
                    Thread.Sleep(timeToGasStation); 
                    Console.WriteLine("[{0}] Arrived at Gas Station", name);

                    // Need to sync here 
                    sync.SignalAndWait(token);

                    // Perform some more work 
                    Console.WriteLine("[{0}] Leaving for Boston", name); 
                } 
                catch (OperationCanceledException) 
                { 
                    Console.WriteLine("[{0}] Caravan was cancelled! Going home!", name); 
                } 
            } 
        } 

    } 

  • 相关阅读:
    vmware磁盘空间扩展
    Winrar发现损坏的压缩文件头
    java ASM动态生成类
    使用ffmpeg将任意格式视频转MP4格式
    mongodb导入csv结构化数据
    Vmware黑屏解决方法
    mysql命令行导入结构化数据
    mysql导入慢解决方法
    CategoryPanelGroup动态生成节点
    delphi XE7 判断手机返回键
  • 原文地址:https://www.cnblogs.com/malaikuangren/p/2534748.html
Copyright © 2011-2022 走看看