私のアプリケーションでは、別のアプリケーションが開始または停止されたことをイベントで通知したいと考えています。私は実行中のアプリケーションに既存の API を持っていますが、これは明らかな解決策である通知に対応するために変更することはできません。
私が持っているのは API の関数呼び出し (isRunning) であるため、API を介して状態をポーリングし、アプリに通知するポーリング スレッドを作成することにしました。
私の問題は、ポーリング スレッドでの API 呼び出しが、自分のアプリケーションのメイン スレッドでも使用されているオブジェクトを使用していることです。それを確実に正しく行う方法を知りたいです :)。
私のアイデアは、API オブジェクトへの各呼び出しを (アダプターを介して、たとえば 2 番目のコード ブロックを参照) ミューテックス ロックでラップすることです。そのため、API が私のスレッドによって複数回呼び出されることはないと確信しています。
これは正しいアプローチですか?
スレッド化/同期にブーストを使用しています (コードを参照)。
これはポーリング スレッドです。
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;
}