多线程常用信号:ManualResetEvent,AutoResetEvent

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();
        }
    }

执行结果如图:
多线程常用信号:ManualResetEvent,AutoResetEvent_第1张图片
可见,没有信号时,WaitOne()后面的语句都不执行(被阻塞),当Set()释放信号后,所有阻塞的线程都开始继续执行。
原文链接:https://blog.csdn.net/u013986317/article/details/87909603

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

你可能感兴趣的:(线程,开发语言,c#)