我想用boost::timed_wait
來等待事件或在5秒後超時。我的問題是我的timed_wait
只接受第一次通知。從boost :: 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?或者我需要以某種方式重置它?歡迎任何建議!
不是答案,因爲我不確定代碼中發生了什麼,但條件變量不僅僅是信號,它們應該用來表示共享條件中的變化。看到這個例子:http://www.justsoftwaresolutions.co.uk/thread/implementing-a-thread-safe-queue-using-condition-variables.html – stefaanv 2012-03-28 11:12:49
在你的代碼中,條件可能是一個忙標誌,所以stateMachine可能有「busy = true; while(busy &&!rc){rc = m_Condition.timed_wait(...);}」 – stefaanv 2012-03-28 11:16:09
@stefaanv感謝您的建議。我讀過你發佈的那篇文章,好吧,也許我使用'timed_wait'不是爲了通常的預期目的,但它仍然應該做這筆交易。其實他們在那裏使用的實現和我的一樣。 給你的第二個評論:忙旗應該做什麼?我的意思是我的問題是我的'timed_wait'只在第一次調用後返回一個超時值和一個返回值'false'。我可以調用'notify_all()'所有我想要的..不會改變任何東西:/ – Toby 2012-03-28 11:22:42