C#多线程通信

  1. 信号量:在C#多线程通信中主要用来向阻塞的线程传达信号从而使得阻塞线程继续执行。代表一种许可的概念,是否允许多线程对同一资源操作的许可。

  2. 多线程信号(线程交互):通常是指线程必须等待一个线程或者多个线程通知交互(释放信号),才可以继续执行。

  3. C#中信号量主要有这几个:

    AutoResetEvent,

    private static AutoResetEvent auto = new AutoResetEvent(false);
    Thread thread = new Thread(AutoReset);//定义线程去执行AutoReset方法
    thread.Start();//开始线程
    Thread.Sleep(5000);//休眠5s
    auto.Set();
    static void AutoReset()
            {
                auto.WaitOne();//阻塞线程,等待释放信号从而继续执行下面的代码,一直等待
                //auto.WaitOne(2000);//等待两秒,如果没有收到信号,则继续执行
                Console.WriteLine("Wait 5s,Begin Run AutoReset");
            }

    ManualResetEvent,

    private static ManualResetEvent manualResetEvent = new ManualResetEvent(false);
    {
                    Thread thread = new Thread(ManualResetEvent);//定义线程去执行AutoReset方法
                    thread.Start();//开始线程
                    Thread.Sleep(5000);//休眠5s
                    manualResetEvent.Set();
                    Thread.Sleep(5000);
                    manualResetEvent.Reset();//和AutoResetEvent区别在于 AutoResetEvent会自动重置状态,ManualResetEvent需要手动Reset为无信号状态,否则二次或者多次waitone无效
    }
    static void ManualResetEvent()
    {
                manualResetEvent.WaitOne();//阻塞线程,等待释放信号从而继续执行下面的代码,一直等待
                //auto.WaitOne(2000);//等待两秒,如果没有收到信号,则继续执行
                Console.WriteLine("Wait 5s,Begin Run manualResetEvent");
     }

    CountdownEvent,

     var CountdownEvent = new CountdownEvent(1000);
                    //CountdownEvent.CurrentCount//当前总数
                    //CountdownEvent.AddCount()//添加1
                    //CountdownEvent.AddCount(10);//添加指定数量
                    //CountdownEvent.InitialCount//总数
                    //CountdownEvent.Reset()//设置为InitialCount初始值
                    //CountdownEvent.Reset(100)//设置为指定初始值
                    Task.Run(() =>
                    {
                        for (int i = 0; i < 1000; i++)
                        {
                            Task.Delay(100);
                            CountdownEvent.Signal();//代表计数器-1
                            Console.WriteLine(CountdownEvent.CurrentCount);
                        }
                    });
                    CountdownEvent.Wait();//等待计数器归0
                    Console.WriteLine("结束");

    EventWaitHandle,

     #region 同AutoResetEvent
                    Thread thread = new Thread(EventWaitHandleAutoReset);//定义线程去执行AutoReset方法
                    thread.Start();//开始线程
                    Thread.Sleep(5000);//休眠5s
                    eventWaitHandle.Set();//如果下方调用SignalAndWait则可以此处注释掉
                    #endregion
                    #region ManualResetEvent
    ​
                    thread = new Thread(EventWaitHandleManualReset);//定义线程去执行AutoReset方法
                    thread.Start();//开始线程
                    //Thread.Sleep(5000);//休眠5s
                    //eventWaitHandleManualReset.Set();同ManualReset一样 下方方法之所以Set  因为下面发了一个信号,并且等待了一个线程,
                    WaitHandle.SignalAndWait(eventWaitHandle, eventWaitHandleManualReset);//eventWaitHandle发出信号Set,eventWaitHandleManualReset阻塞线程等待信号,EventWaitHandleManualReset发出信号后可以执行Console。WriteLine,否则一直阻塞
                    Console.WriteLine();
                    #endregion
            static void EventWaitHandleAutoReset()
            {
                eventWaitHandle.WaitOne();//阻塞线程,等待释放信号从而继续执行下面的代码,一直等待
                //auto.WaitOne(2000);//等待两秒,如果没有收到信号,则继续执行
                Console.WriteLine("Wait 5s,Begin Run EventWaitHandle AutoReset");
                Thread.Sleep(5000);
            }
            static void EventWaitHandleManualReset()
            {
                Thread.Sleep(5000);//休眠5s等待SignalAndWait阻塞线程,此处释放
                eventWaitHandleManualReset.Set();
                //eventWaitHandleManualReset.WaitOne();//阻塞线程,等待释放信号从而继续执行下面的代码,一直等待
                //auto.WaitOne(2000);//等待两秒,如果没有收到信号,则继续执行
                Console.WriteLine("Wait 5s,Begin Run EventWaitHandle ManualReset");
            }

    Semaphore

    private static Semaphore Semaphore = new Semaphore(3, 3);
    for (int i = 0; i <= 10; i++)
                    {
                        Thread thread = new Thread(new ParameterizedThreadStart(SemaphoreTest));
                        thread.Start(i);
                    }
    Semaphore.WaitOne();//阻塞线程,等待计数器小于设置的初始值后可以进入
                Console.WriteLine(state + "进入了资源");
                Thread.Sleep((int)state * 1000);
                Semaphore.Release();//释放信号,计数器+1
                Console.WriteLine(state + "离开了了资源"

  4. 非终止状态(无信号):线程受阻        终止状态线程执行(有信号):线程执行

  5. Sleep函数:让当前线程暂停执行一段时间,通常用于模拟实际运行环境下的等待或延时操作。

    Thread.Sleep(0):指定零 (0) 以指示应挂起此线程以使其他等待线程能够执行。并非是真的要线程挂起0毫秒,意义在于这次调用Thread.Sleep(0)的当前线程确实的被冻结了一下,让其他线程有机会优先执行。Thread.Sleep(0) 是你的线程暂时放弃cpu,也就是释放一些未用的时间片给其他线程或进程使用,就相当于一个让位动作。

参考文章:C# Semaphore 信号量 锁 简单理解 - 小林野夫 - 博客园 (cnblogs.com)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值