0

In my application I want to be informed by events, that another application has been started or stopped. I have an existing API to the running application which cannot be changed to accomodate notification which would be the obvious solution.

What I have is a function call in the API (isRunning), so I decided to make a polling thread which polls the state through the API and informs my app.

My problem is now, the API call in the polling thread uses an object which is also used in my own application's main thread and I'd like to know how to be sure that I make it right :).

My idea would be to wrap each call to the API object (through an adapter e.g., see the second code block) with a mutex lock, so I'm sure the API is not called by my threads more than once.

Is this the right approach?

I'm using boost for threading/syncing (see code).

This is the polling thread:

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();
        }
    }
}

These are some API calls from the main thread:

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;
}
4

1 回答 1

0

这听起来是个不错的方法。

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

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

于 2009-03-20T19:08:26.987 回答