Dans mon application, je souhaite être informé par les événements qu'une autre application a été démarrée ou arrêtée. J'ai une API existante à l'application en cours d'exécution qui ne peut pas être modifié pour accueillir la notification qui serait la solution évidente. Ce que j'ai est un appel de fonction dans l'API (isRunning), j'ai donc décidé de faire un thread d'interrogation qui interroge l'état via l'API et informe mon application.Comment synchroniser les threads lors de l'interrogation des changements d'état avec boost
Mon problème est maintenant, l'appel API dans le thread d'interrogation utilise un objet qui est également utilisé dans le thread principal de mon propre application et je voudrais savoir comment être sûr que je le fais bien :). Mon idée serait d'enrouler chaque appel à l'objet API (via un adaptateur par exemple, voir le deuxième bloc de code) avec un verrou mutex, donc je suis sûr que l'API n'est pas appelée par mes threads plus d'une fois.
Est-ce la bonne approche? J'utilise boost pour l'enfilage/la synchronisation (voir le code).
C'est le fil conducteur de vote:
void EventCreator::start()
{
stop();
m_bShouldRun = true;
m_spThread = BoostThreadPtr(new thread(bind(&EventCreator::run,this)));
}
void EventCreator::stop()
{
{
lock_guard<mutex> lock(m_mutex);
m_bShouldRun = false;
m_condition.notify_one();
}
if (m_spThread)
{
m_spThread->join();
m_spThread.reset();
}
}
void EventCreator::run()
{
bool isRTAppRunning = m_pDevice->isApplicationRunning();
while (m_bShouldRun)
{
boost::unique_lock<mutex> lock(m_mutex);
//
if(!m_condition.timed_wait(lock,boost::system_time(boost::get_system_time() + boost::posix_time::milliseconds(25))))
{
// here because of time out, so no sleep necessary
bool isStillRunning = m_pDevice->isApplicationRunning();
if (isRTAppRunning != isStillRunning)
{
if (isStillRunning)
{
// Using SendMessage to main thread => no problem here
notifyAppStarted();
}
else
{
notifyAppStopped();
}
isRTAppRunning = isStillRunning;
}
// in addition to wait above
m_spThread->yield();
}
}
}
Voici quelques appels API du thread principal:
void Device::getData(Int32 byteCnt)
{
mutex::scoped_lock lock(m_monitor);
m_pApi->fetchBytes(&m_buf,byteCnt);
}
bool Device::isApplicationRunning()
{
mutex::scoped_lock lock(m_monitor);
return m_pApi->getState() == DV_RUNNING;
}