В моем приложении я хочу получать уведомления о событиях, что другое приложение было запущено или остановлено. У меня есть существующий API для работающего приложения , который нельзя изменить для размещения уведомлений, что было бы очевидным решением.
У меня есть вызов функции в API (isRunning), поэтому я решил создать поток опроса, который опрашивает состояние через API и информирует мое приложение.
Моя проблема в том, что вызов API в потоке опроса использует объект, который также используется в основном потоке моего собственного приложения, и я хотел бы знать, как быть уверенным, что я все делаю правильно:).
Моя идея заключалась бы в том, чтобы обернуть каждый вызов объекта API (через адаптер, например, см. Второй блок кода) блокировкой мьютекса, поэтому я уверен, что API не вызывается моими потоками более одного раза.
Это правильный подход?
Я использую boost для многопоточности / синхронизации (см. Код).
Это тема опроса:
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();
}
}
}
Вот некоторые вызовы API из основного потока:
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;
}