• Thread in depth 4:Synchronous primitives


    There are some synchronization primitives in .NET used to achieve thread synchronization

    Monitor

    c# provides System.Threading.Monitor class which cooperates with an objcet to implement locking. Every object has a sync block inside its data stucture,which used by the Monitor to mark down if it is referenced by one thread .The lock statement in c# is implemented by Monitor,and it uses try...catch..finally block to ensure the lock will be released even exception occurs.

    Knowing Monitor uses sync block of a object to implement thread locking is helpful to understand the behavior of the lock statement.The figure below describes what happens when using lock statement.

    Mutex

    The System.Threading.Mutex class derives from System.Threading.WaitHandle class,so Threads request a mutex by calling its WaitOne method, and it provides some overloads to WaitOne method supporting the timeout of waitting.In addition,you can also use the WaitAll,WaitAny or SignalAndWait methods

    SpinLock

    C# provides a System.Threading.SpinLock class to implement the spin locking. Spin Lock means it will let the thread keep running in loop until it has the access permission to the resource.In most time,OS uses kernel wait handle to block the thread if use synchronous primitives which derives from WaitHandle,like semaphore and WaitEvent class, that means the execution will go through from the managed code and native kernel method, this will bring a performance issue.However, if the lock is held for a very short time,then let the thread run in loop will have a better performance.Of course, keep the thread running can cause a thread context switch and an occupation to CPU, so think twise before using it.

    Semaphore

    The System.Threading.Semaphore derives from WaitHandle,so can use WaitOne method or WaitAny,WaitAll static method just like Mutex class ,and it allows a specified number of threads to access a resourceIn addional, you can specify a name to a semaphore, a semaphore won't block another thread which has a semaphore of a different name.check the codes below:

        public class SyncSample
        {
            public void DoWork()
            {
                Semaphore s = new Semaphore(1, 10, "name_of_semaphore");
                s.WaitOne();
                Console.WriteLine("doing work");
                Thread.Sleep(3000);
                Console.WriteLine("work done");
                s.Release();
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                SyncSample sc = new SyncSample();
                Task.Run(() => { sc.DoWork(); });
                Task.Run(() => { sc.DoWork(); });
                Console.Read();
            }
        }

    The result is:

     If we specify another name, no thread will be blocked:

        public class SyncSample
        {
            public void DoWork()
            {
                Semaphore s = new Semaphore(1, 10, Guid.NewGuid().ToString());//will get a different name here
                s.WaitOne();
                Console.WriteLine("doing work");
                Thread.Sleep(3000);
                Console.WriteLine("work done");
                s.Release();
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                SyncSample sc = new SyncSample();
                Task.Run(() => { sc.DoWork(); });
                Task.Run(() => { sc.DoWork(); });
                Console.Read();
            }
        }

    The result is:

    EventWaitHandle

    [MSDN]System.Threading.EventWaitHandle class threads to communicate with each other by signaling.Typically,one or more threads block on an EventWaitHandle until an unblocked thread calls the Set method,releasing one or more of the blocked threads.A thread can signal an EventWaitHandle and then block on it,by calling the static WaitHandle.SignalAndWait method.

    The constructor accepts an initialState parameter,indicating the initial state of the EventWaitHandler:true then signaled and false is nonsignaled.

    The other parameter you can pass into the constructor is EventResetMode enum,being used to controll the behavior of the EventWaitHandle to be AutoReset or ManualRest.AutoRest means the EventWaitHandler is just like a fitting room that has a signal light indicating if it is available or not.When a person gets into the room, the signal light will be off automatically, when the person gets out,the signal light will be turned on automatically ,waitting another person to get in.  On the other hand,ManualRest means the EventWaitHandle is like a gate of the zoo, if the admin open the gate ,ALL waitting people rush into the zoo, until the admin close the gate again, then others people who not yet get into the zoo have to wait for the gate open again.

    See also:

    WaitHandle Class

    Overview of Synchronization Primitives

    AutoResetEvent Class

    ManualResetEvent Class

     

  • 相关阅读:
    第九章、硬件抽象层:HAL
    第八章、让开发板发出声音:蜂鸣器驱动
    第七章、LED将为我闪烁:控制发光二极管
    第六章、第一个Linux驱动程序:统计单词个数
    第五章、搭建S3C6410开发板的测试环境
    Android深度探索(卷1)HAL与驱动开发
    第三次月考
    第二次月考
    Android深度探索(卷1)HAL与驱动开发
    第六章 集合运算
  • 原文地址:https://www.cnblogs.com/lwhkdash/p/6790469.html
Copyright © 2020-2023  润新知