c# - Monitor.Pulse 和 Monitor.Wait 有什么优势?

标签 c# multithreading concurrency

我对并发编程有点陌生,正在尝试了解使用 Monitor.Pulse 和 Monitor.Wait 的好处。

MSDN 的例子如下:

class MonitorSample
{
    const int MAX_LOOP_TIME = 1000;
    Queue   m_smplQueue;

    public MonitorSample()
    {
        m_smplQueue = new Queue(); 
    }
    public void FirstThread()
    {
        int counter = 0;
        lock(m_smplQueue)
        {
            while(counter < MAX_LOOP_TIME)
            {
                //Wait, if the queue is busy.
                Monitor.Wait(m_smplQueue);
                //Push one element.
                m_smplQueue.Enqueue(counter);
                //Release the waiting thread.
                Monitor.Pulse(m_smplQueue); 

                counter++;
            }
        }
    }
    public void SecondThread()
    {
        lock(m_smplQueue)
        {
            //Release the waiting thread.
            Monitor.Pulse(m_smplQueue);
            //Wait in the loop, while the queue is busy.
            //Exit on the time-out when the first thread stops. 
            while(Monitor.Wait(m_smplQueue,1000))
            {
                //Pop the first element.
                int counter = (int)m_smplQueue.Dequeue();
                //Print the first element.
                Console.WriteLine(counter.ToString());
                //Release the waiting thread.
                Monitor.Pulse(m_smplQueue);
            }
        }
    }
    //Return the number of queue elements.
    public int GetQueueCount()
    {
        return m_smplQueue.Count;
    }

    static void Main(string[] args)
    {
        //Create the MonitorSample object.
        MonitorSample test = new MonitorSample();           
        //Create the first thread.
        Thread tFirst = new Thread(new ThreadStart(test.FirstThread));
        //Create the second thread.
        Thread tSecond = new Thread(new ThreadStart(test.SecondThread));
        //Start threads.
        tFirst.Start();
        tSecond.Start();
        //wait to the end of the two threads
        tFirst.Join();
        tSecond.Join();         
        //Print the number of queue elements.
        Console.WriteLine("Queue Count = " + test.GetQueueCount().ToString());
    }
}

我看不到使用 Wait And Pulse 代替这个的好处:

    public void FirstThreadTwo()
    {
        int counter = 0;
        while (counter < MAX_LOOP_TIME)
        {
            lock (m_smplQueue)
            {
                m_smplQueue.Enqueue(counter);
                counter++;
            }
        }
    }
    public void SecondThreadTwo()
    {
        while (true)
        {
            lock (m_smplQueue)
            {
                    int counter = (int)m_smplQueue.Dequeue();
                    Console.WriteLine(counter.ToString());
            }
        }
    }

非常感谢任何帮助。 谢谢

最佳答案

要描述“优势”,一个关键问题是“超过什么?”。如果您的意思是“优先于热循环”,那么 CPU 利用率是显而易见的。如果您的意思是“优先于 sleep /重试循环”- 您可以获得更快的响应(Pulse 不需要等待那么久)并且使用较低的 CPU(你没有不必要地醒来 2000 次)。

不过,一般来说,人们的意思是“优先于 Mutex 等”。

我倾向于广泛地使用这些,甚至优先于互斥锁、重置事件等;原因:

  • 它们很简单,涵盖了我需要的大部分场景
  • 它们相对便宜,因为它们不需要一直到操作系统句柄(不像 Mutex 等,它们由操作系统拥有)
  • 我通常已经使用来处理同步,所以当我需要等待时,我很可能已经有了为了某事
  • 它实现了我的正常目标 - 允许 2 个线程以托管方式向彼此发送完成信号
  • 我很少需要 Mutex 等的其他功能(例如进程间)

关于c# - Monitor.Pulse 和 Monitor.Wait 有什么优势?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6575723/

相关文章:

c# - 等待锁定执行的任务数组

c# - 在枚举期间添加和删除 ConcurrentBag 的元素

c# - 在解决方案中的项目之间共享 PartialView?

C# 接口(interface)重载实现

c# - 读取和处理每个约 100Mb 的大型文本文件

java - 从写入器向读取器发送信号时正确使用 ReentrantReadWriteLock?

java - 如何在并发环境中设计到数据库的http连接(是否为静态变量)

c# - 使用 Sqlite 数据库捕获、保存和检索图像/图片

c# - 未完成时终止异步委托(delegate)线程

c - 创建用户输入的多个线程时出现段错误