c#中多线程间的同步

C#笔记 ningjian
 public class Sample
    {   //先执行的线程设置为 true
        ManualResetEvent even = new ManualResetEvent(true);
        ManualResetEvent odd = new ManualResetEvent(false);        
        
        public void Sum()
        {           
            var ta = Task.Run(() => PrintEven(even, odd));
            var tb = Task.Run(() => PrintOdd (even,odd));                      
        }
				//等待自己的信号,控制另一个线程的信号
        public void PrintEven(EventWaitHandle evenHandle, EventWaitHandle oddHandle)
        {            
            string design =  "偶数";
            for (int i = 0; i <= 20; i++)
            {               
                evenHandle.WaitOne();
                if ((i & 1) == 0)
                {
                    Console.WriteLine($"{design}:{i}");
                    evenHandle.Reset();
                    oddHandle.Set();
                }
            }
        }
        public void PrintOdd(EventWaitHandle evenHandle, EventWaitHandle oddHandle)
        {
            string design = "奇数";
            for (int i = 0; i <= 20; i++)
            {               
                oddHandle.WaitOne();
                if ((i & 1) == 1)
                {
                    Console.WriteLine($"{design}:{i}");
                    oddHandle.Reset();
                    evenHandle.Set();
                }
            }
        }
    }

 

 

Event

与信号量一样,事件也是一个系统范围内的资源同步方法。又分为ManualResetEvent,AutoResetEvent,CountdownEvent以及ManualResetEventSlim,在构建对象实例时若传入了name参数,代表这是一个可以跨进程的系统级同步事件。

以 ManualResetEvent 为例,该类有 signaled 和 nonsignaled 两种状态,这两种状态通过实例化对象时的 布尔类型 参数决定,TRUE 就是signaled, False相反

文档中常见的翻译是发出信号的状态和未发出信号的状态,微软官网的机翻是终止状态和非终止状态,还有一些释放线程之类的描述,直观上难以理解。其实就是改变状态而已,还不如英文的好理解。

ManualResetEvent 的基类 EventWaitHandle 中提供了Set() 和Reset() 方法,用于改变状态,Set 将事件修改为 signaled,Reset重置为 nonsignaled

这里说一下Set和Reset,这两个方法是改变了事件的状态,并不是一个瞬时性的动作,也就意味着在调用Set后,调用Reset之前,事件都处于 signaled 状态(AutoResetEvent会自动调用Reset重置事件状态)

WaitHandle 类中提供了众多等待信号的方法,EventWaitHandle 继承自WaitHandle, ManualResetEvent中也可以调用WaitOne等方法。

回头再看一下信号量 Semaphore 的示例,也调用 WaitOne 等待信号,因为它也继承自 Waithandler。

 

发表评论:

验证码