在我的应用程序中,我想通过事件获知,另一个应用程序已经启动或停止。我有正在运行的应用程序的现有API,无法更改以容纳通知,这是明显的解决方案。
我所拥有的是API中的函数调用(isRunning),因此我决定创建一个轮询线程,通过API轮询状态并通知我的应用程序。
现在我的问题是,轮询线程中的API调用使用了一个对象,该对象也在我自己的应用程序的主线程中使用,我想知道如何确保我做对了:)。
我的想法是使用互斥锁将每次调用包装到API对象(通过适配器,例如,查看第二个代码块),所以我确信我的线程不会多次调用API。< / p>
这是正确的方法吗?
我正在使用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;
}
答案 0 :(得分:0)
这听起来像是一个很好的方法。
一般来说,锁定应该非常快,以便在无竞争时获得。您的轮询线程应该不经常轮询,即每隔几秒最多一次,因此对锁的争用应该非常小。
如果你的两个线程一直在争夺锁定,你需要重新考虑你的设计。