【问题标题】:How to synchronize threads when polling for state changes with boost使用boost轮询状态更改时如何同步线程
【发布时间】:2010-10-14 14:58:51
【问题描述】:

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

【问题讨论】:

    标签: synchronization locking monitor boost-thread


    【解决方案1】:

    这听起来是个好方法。

    一般来说,锁在非竞争状态下应该非常快地获取。您的轮询线程应该不经常轮询,即最多每隔几秒钟轮询一次,因此对锁的争用应该非常小。

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

    【讨论】:

      猜你喜欢
      • 2018-07-10
      • 1970-01-01
      • 1970-01-01
      • 2011-04-15
      • 1970-01-01
      • 2014-08-10
      • 2015-09-23
      • 1970-01-01
      相关资源
      最近更新 更多