【问题标题】:Boost equivalent of ManualResetEvent?提升等效于 ManualResetEvent?
【发布时间】:2010-12-02 20:01:14
【问题描述】:

我想知道是否有相当于 ManualResetEvent 的提升?基本上,我想要一个跨平台的实现......或者,有人可以帮助我使用 Boost::thread 模仿 ManualResetEvent 的功能吗?谢谢大家

【问题讨论】:

  • 您要模拟哪些事件函数?

标签: c++ multithreading boost thread-safety


【解决方案1】:

当您有互斥锁和条件变量时,编写手动重置事件非常容易。

您将需要一个表示您的重置事件是否已发出信号的字段。对字段的访问需要由互斥锁保护 - 这包括设置/重置您的事件以及检查它是否已发出信号。

当您等待您的事件时,如果它当前没有发出信号,您将希望等待一个条件变量,直到它发出信号。最后,在设置事件的代码中,您需要通知条件变量以唤醒等待您事件的任何人。

class manual_reset_event
{
public:
    manual_reset_event(bool signaled = false)
        : signaled_(signaled)
    {
    }

    void set()
    {
        {
            boost::lock_guard<boost::mutex> lock(m_);
            signaled_ = true;
        }

        // Notify all because until the event is manually
        // reset, all waiters should be able to see event signalling
        cv_.notify_all();
    }

    void unset()
    {
        boost::lock_guard<boost::mutex> lock(m_);
        signaled_ = false;
    }


    void wait()
    {
        boost::lock_guard<boost::mutex> lock(m_);
        while (!signaled_)
        {
            cv_.wait(lock);
        }
    }

private:
    boost::mutex m_;
    boost::condition_variable cv_;
    bool signaled_;
};

【讨论】:

  • 我认为您可能需要使用 boost::condition_variable_any 才能使其正常工作。见:stackoverflow.com/questions/8758353/…
  • 另外,condition_variable_any::wait 方法必须将互斥锁作为参数,而不是锁守卫。
  • 嗯,我得到:错误 C2664 'void boost::condition_variable::wait(boost::unique_lock &)':无法从 'boost::lock_guard' 转换参数 1到 'boost::unique_lock &' 它我使用 condition_variable_any,我在 condition_variable 中得到另一个错误,关于 unlock() 方法不存在。
【解决方案2】:

IIRC,ManualResetEvents 的存在是为了允许多个线程等待一个对象,并且在对象发出信号时一次唤醒一个线程。 “手动重置”部分来自于系统在唤醒线程后不会自动重置事件;你可以这样做。

这听起来很像condition variables:

一般的使用模式是一个线程锁定一个互斥体,然后在condition_variablecondition_variable_any 的实例上调用wait。当线程从等待中唤醒时,它会检查适当的条件现在是否为真,如果是则继续。如果条件不成立,则线程再次调用wait 继续等待。

【讨论】:

  • 我基本上只有一个写入器线程,它必须始终写入并且永远不会被阻塞,而我有一个读取器线程只能在写入器不写入时读取......如果这有意义的话。谢谢
  • 我会说你的设计很有道理。
猜你喜欢
  • 1970-01-01
  • 2011-02-26
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
  • 2013-09-16
  • 1970-01-01
相关资源
最近更新 更多