多线程常用信号:ManualResetEvent,AutoResetEvent

本文详细介绍了C#中的ManualResetEvent类,如何通过Set和Reset方法控制信号,以及WaitOne方法如何让线程阻塞和接收信号。通过示例展示了如何使用ManualResetEvent实现线程间的同步控制。
摘要由CSDN通过智能技术生成

1.了解信号

在这两个信号中:

1.Set方法可以将信号置为发送状态;

        释放信号,所有等待信号的线程都将获得信号,开始执行WaitOne()后面的语句;

        将事件状态设置为中,终止状态许一个或多个的等待线程继续

2.Reset方法将信号置为不发送状态:

        一旦我们调用了ManualResetEvent对象的Set()方法,它的bool值就变为true,我们可以调用Reset()方法来重置该值,Reset()方法重置该值为False

3.WaitOne等待信号的发送(在需要等待信号的线程中调用WaitOne方法,该方法会阻塞当前线程,直到收到信号);该方法阻塞当前线程并等待其他线程发送信号。如果收到信号,它将返回True,反之返回False。

         多个线程可以通过调用ManualResetEvent对象的WaitOne方法进入等待或阻塞状态。当控制线程调用Set()方法,所有等待线程将恢复并继续执行。

        我们可以通过构造函数的参数值来决定其初始状态,若为true则非阻塞状态,为false为阻塞状态。如果某个线程调用WaitOnef方法,则当信号处于发送状态时,线程会得到信号,继续向下执行。

 2.ManualResetEvent——可以对所有进行等待的线程进行统一控制

   2.1  ManualResetEvent是如何工作的     

        在内存中保持着一个bool值,如果bool值为False,则使所有线程阻塞,反之,如果bool值为True,则使所有线程退出阻塞。当我们创建ManualResetEvent对象的实例时,我们在函数构造中传递默认的bool值。

        ManualResetEvent manualResetEvent = new ManualResetEvent(false);

在上面代码中,我们初始化了一个值为False的ManualResetEvent对象,这意味着所有调用WaitOne放的线程将被阻塞,直到有线程调用了 Set() 方法。而如果我们用值True来对ManualResetEvent对象进行初始化,所有调用WaitOne方法的线程并不会被阻塞,可以进行后续的执行

   2.2   如何使用

class Program
    {
        static void Main(string[] args)
        {
            //注意:ManualResetEvent可以对所有进行等待的线程进行统一控制
 
            //true-初始状态为发出信号;false-初始状态为未发出信号
            ManualResetEvent mre = new ManualResetEvent(false);
            //线程池开启10个线程
            for (int i = 0; i < 10; i++)
            {
                int k = i;
                
                ThreadPool.QueueUserWorkItem(t =>
                {
                    Console.WriteLine($"这是第{k+1}个线程,线程ID为{Thread.CurrentThread.ManagedThreadId}");
                    //等待信号,没有信号的话不会执行后面的语句,因为初始状态是false,所以后面的语句暂时不会执行
                    mre.WaitOne();
                    Console.WriteLine($"第{k+1}个线程获得信号,线程ID为{Thread.CurrentThread.ManagedThreadId}");
                });
            }
            Thread.Sleep(5000);
            Console.WriteLine("\r\n 5秒后发出信号... \r\n");
            //Set()方法:释放信号,所有等待信号的线程都将获得信号,开始执行WaitOne()后面的语句
            mre.Set();
            Console.ReadKey();
        }
    }

执行结果如图:
在这里插入图片描述
可见,没有信号时,WaitOne()后面的语句都不执行(被阻塞),当Set()释放信号后,所有阻塞的线程都开始继续执行。
原文链接:https://blog.csdn.net/u013986317/article/details/87909603

原文:http://www.cnblogs.com/li-peng/p/3291306.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薄荷撞~可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值