【问题标题】:Multiple wait on the same lock多个等待同一个锁
【发布时间】:2013-10-09 16:30:09
【问题描述】:

我对锁定有点困惑。具体来说,这段代码来自维基百科,关于消费者生产者问题。

http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem#Example_in_C.2B.2B

如果有超过 1 个生产者等待添加到队列中会发生什么?如果消费者从队列中消费了一些作业并发出通知以指示队列未满,他们都会尝试将作业推送到队列中,这需要 queue.push 方法是线程安全的。由于他们都可以修改队列,因此此代码可能会中断。我错过了什么吗?

【问题讨论】:

    标签: c++ multithreading c++11


    【解决方案1】:

    是的,您错过了 xmutex 被锁定的事实,因此一次只有一个生产者可以推送任何内容。

    当您等待condition_variable 时,您必须向它传递一个锁定的互斥体,该互斥体将在等待时解锁。当等待调用返回时,互斥锁将被重新锁定。

    虽然所有生产者都会收到is_not_full.notify_all(); 事件的通知,因此都会被唤醒,但他们一次只能重新获得xmutex 上的锁定。这就是互斥锁的全部意义所在。

    【讨论】:

    • 最重要的是,无论如何,您通常只有一个制作人。如果已经有许多生产者并行运行,那么它们也可以承担消费者的工作。生产者/消费者(除了极少数例外)的要点是将 n 个可并行化的任务平均分配到 m 个工作线程或执行核心上。如果希望有多个生产者,信号量将是一种更明智的实现(避免您提到的雷鸣般的羊群问题)。
    • 这个实现还有另一个问题。如果生产者多于 max_products,在本例中等于 10,则可能有 10 个生产者在等待,当它们都被唤醒时,它们都会加入队列,虽然它是线程安全的,但队列中的产品数量可以超过 10 个,这是允许的最大值。
    猜你喜欢
    • 2018-10-07
    • 2011-11-01
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    相关资源
    最近更新 更多