从boost :: timed_wait通知条件变量只能工作一次

时间:2012-03-28 09:59:59

标签: c++ multithreading boost asynchronous

我想使用boost::timed_wait等待事件或在5秒后超时。我的问题是我的timed_wait只是第一次接受通知。

更确切地说:

我有一些小型的状态机。它只是异步调度一些命令,然后检查它是否成功。这意味着在调度命令后,我的状态机调用m_Condition.timed_wait(lock,timeout)。 (m_Condition是类型为boost::condition_variable)的成员变量。

现在,如果这个异步调用成功,它将调用一个回调函数,通知m_Condition,所以我知道一切正常。当命令失败时,它不会调用回调函数,所以我的timed_wait应该超时。所以回调函数除了调用m_Condition.notify_all()之外什么都没做。

问题是这只能在第一次使用。这意味着,在第一次调用notify_all()之后,它再次无法使用该条件变量。我检查了我的回调,它总是再次调用notify_all(),但timed_wait只是超时。

也许一些示例代码使它更清晰:

myClass_A.hpp

class myClass_A
{
public:
    void runStateMachine();                 // Starts the state machine
    void callbackEvent();                   // Gets called when Async Command was successful
private:
    void stateMachine();                    // Contains the state machine
    void dispatchAsyncCommand();            // Dispatches an Asynchronous command
    boost::thread m_Thread;                 // Thread for the state machine
    boost::condition_variable m_Condition;  // Condition variable for timed_wait
    boost::mutex m_Mutex;                   // Mutex
};

myClass_A.cpp

void myClass_A::runStateMachine()
{
     m_Thread = boost::thread(boost::bind(&myClass_A,this));
}
void myClass_A::dispatchAsyncCommand()
{
     /* Dispatch some command Async and then return */
     /* The dispatched Command will call callbackEvent() when done */
}
void myClass_A::stateMachine()
{
    boost::mutex::scoped_lock lock(m_Mutex);
    while(true)
    {
        dispatchAsynCommand();
        if(!m_Condition.timed_wait(lock, boost::posix_time::milliseconds(5000)))
        {
            // Timeout
        }
        else
        {
            // Event
        }
    }
}
void myClass_A::callbackEvent()
{
    boost::mutex::scoped_lock lock(m_Mutex);
    m_Condition.notify_all();
}

那我现在该怎么办?是不是可以多次使用condition_variable?或者我需要以某种方式重置它?欢迎任何建议!

2 个答案:

答案 0 :(得分:0)

不,您不必重置条件变量,是的,它可以多次运行。

我相信你所看到的是一个死锁,而不是在第二次等待m_condition时失败。当你在stateMachine()中调用timed_wait()时,你的互斥锁将被解锁,并在timed_wait()返回时被重新锁定。我猜测在等待的丢失代码中你调用callbackEvent()。该方法试图锁定互斥锁,但它不能,因为(a)它已经锁定在调用者(stateMachine())和(b)boost :: mutex不可重入。您可以尝试使用例如而是recursive_mutex。

答案 1 :(得分:0)

好吧,对我来说不是最亮的时刻,我实际上解决了这个问题。上面发布的代码正在编译并按预期工作。实际问题在于处理事件或超时。因为那里发生的事情与timed_wait完全无关,我想我不需要在这里解释它。所以这个问题可以关闭。

<强>更新

当然,由于缺少调度方法,上述代码将无效。只是为了它,我在这里提一下:为了测试目的,我只需在我的main函数中创建一个myClass_A的Object,启动状态机,然后从我的main函数调用callbackEvent。这实际上有效!