如何在使用boost轮询状态更改时同步线程

时间:2009-03-20 18:44:29

标签: synchronization locking monitor boost-thread

在我的应用程序中,我想通过事件获知,另一个应用程序已经启动或停止。我有正在运行的应用程序的现有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;
}

1 个答案:

答案 0 :(得分:0)

这听起来像是一个很好的方法。

一般来说,锁定应该非常快,以便在无竞争时获得。您的轮询线程应该不经常轮询,即每隔几秒最多一次,因此对锁的争用应该非常小。

如果你的两个线程一直在争夺锁定,你需要重新考虑你的设计。