boost::timed_wait
を使用して、イベントを待つか、5秒後にタイムアウトします。私の問題は、私のtimed_wait
が初めて通知を受け入れるということです。boost :: timed_waitからの通知条件変数は一度しか動作しません
より正確には:
私は少しステートマシンのいくつかの種類があります。 Commandだけを非同期的にディスパッチし、それが正常に実行されたかどうかをチェックするだけでは何も行いません。これは、私の状態マシンが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/threading/implementing-a-thread-safe-queue-using-condition-variables.html – stefaanv
あなたのコードでは、状態はビジー状態のフラグなので、stateMachine "busy = true; while(busy &&!rc){rc = m_Condition.timed_wait(...);}" – stefaanv
@stefaanvあなたの提案をありがとう。私はあなたが投稿した記事を読んで、大丈夫です、たぶん私は 'timed_wait'を通常の意図した目的ではなく使っていますが、それでもやるべきことです。実際にそこで使った実装は、私のものと全く同じです。 2番目のコメントに:どのようなビジーフラグを行う必要がありますか?私の問題は、私の 'timed_wait'は最初の呼び出しの後にタイムアウトと' false'の戻り値だけを返すということです。私は 'notify_all()'を呼び出すことができます。何も変更しません:/ – Toby