【发布时间】:2012-03-28 09:59:59
【问题描述】:
我想使用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吗?还是我需要以某种方式重置它?欢迎提出任何建议!
【问题讨论】:
-
不是答案,因为我不确定您的代码中发生了什么,但条件变量不仅仅是信号,它们应该用于表示共享条件的变化。请参阅此示例:justsoftwaresolutions.co.uk/threading/…
-
在您的代码中,条件可能是繁忙标志,因此 stateMachine 可能具有“busy = true; while (busy && !rc) { rc = m_Condition.timed_wait(...); }”
-
@stefaanv 感谢您的建议。我读了你发布的那篇文章,好吧,也许我使用
timed_wait不是为了通常的预期目的,但它仍然应该做交易。实际上他们在那里使用的实现和我的完全一样。对于您的第二条评论:那个忙碌的旗帜应该做什么?我的意思是我的问题是我的timed_wait仅在第一次调用后返回超时和false的返回值。我可以打电话给notify_all()我想要的一切..不会改变任何东西:/ -
实际上,我看不出它在您的代码中可能失败的地方,因为 notify_all 只能在互斥锁被锁定时调用,这意味着另一个线程处于 timed_wait 中,但仍然没有那么困难包括忙碌标志并查看(文档提到您最好在执行相对 timed_wait 时传递谓词)
-
如果在您的 while(true) 循环中解锁互斥锁,则可以在线程处于 timed_wait 之前调用 notify_all。
标签: c++ multithreading boost asynchronous