POCO线程类分析

  • 最简单的Poco线程调用方式:
Thread thread;
MyRunnable r;
thread.start(r);
  • 关注的重点,就是MyRunnable:线程的运行体。
class MyRunnable: public Runnable
{
public:
    MyRunnable(): _ran(false)
    {
    }

    void run()
    {
        Thread* pThread = Thread::current();
        if (pThread)
            _threadName = pThread->name();
        _ran = true;
        _event.wait();
    }

    bool ran() const
    {
        return _ran;
    }

    const std::string& threadName() const
    {
        return _threadName;
    }

    void notify()
    {
        _event.set();
    }

    static void staticFunc()
    {
        ++_staticVar;
    }

    static int _staticVar;

private:
    bool _ran;
    std::string _threadName;
    Event _event;
};


int MyRunnable::_staticVar = 0;
  • 此类继承于Runnable:
class Foundation_API Runnable
    /// The Runnable interface with the run() method
    /// must be implemented by classes that provide
    /// an entry point for a thread.
{
public: 
    Runnable();
    virtual ~Runnable();

    virtual void run() = 0;
        /// Do whatever the thread needs to do. Must
        /// be overridden by subclasses.
};


} 
  • 自定义的MyRunnable只需要实现Runnable的run()方法即可。到此Poco的线程调用过程都已完成,我们接着分析具体的内部实现机制,首先查看start()方法:
void Thread::start(Runnable& target)
{
    startImpl(target);
}
  • 传一个Runnable实例对象,接着调用startImpl方法:
void ThreadImpl::startImpl(Runnable& target)
{
    if (isRunningImpl())
        throw SystemException("thread already running");

    _pRunnableTarget = ⌖

    createImpl(runnableEntry, this);
}
  • 我们看到,这个函数将Runnable的对象保存到_pRunnableTarget中,具体用法在runnableEntry进行实现:
#if defined(_DLL)
DWORD WINAPI ThreadImpl::runnableEntry(LPVOID pThread)
#else
unsigned __stdcall ThreadImpl::runnableEntry(void* pThread)
#endif
{
    _currentThreadHolder.set(reinterpret_cast<ThreadImpl*>(pThread));
#if defined(_DEBUG) && defined(POCO_WIN32_DEBUGGER_THREAD_NAMES)
    setThreadName(-1, reinterpret_cast<Thread*>(pThread)->getName().c_str());
#endif
    try
    {
        reinterpret_cast<ThreadImpl*>(pThread)->_pRunnableTarget->run();
    }
    catch (Exception& exc)
    {
        ErrorHandler::handle(exc);
    }
    catch (std::exception& exc)
    {
        ErrorHandler::handle(exc);
    }
    catch (...)
    {
        ErrorHandler::handle();
    }
    return 0;
}
  • 这个就是我们正常的线程体函数,而这里面主要进行了:线程属性的保存和reinterpret_cast<ThreadImpl*>(pThread)->_pRunnableTarget->run();执行run函数,自然调用的就是MyRunnable的run方法了,到这边我们找到正常线程写法的端倪。最后就是createImpl的方法:
void ThreadImpl::createImpl(Entry ent, void* pData)
{
#if defined(_DLL)
    _thread = CreateThread(NULL, _stackSize, ent, pData, 0, &_threadId);
#else
    unsigned threadId;
    _thread = (HANDLE) _beginthreadex(NULL, _stackSize, ent, this, 0, &threadId);
    _threadId = static_cast<DWORD>(threadId);
#endif
    if (!_thread)
        throw SystemException("cannot create thread");
    if (_prio != PRIO_NORMAL_IMPL && !SetThreadPriority(_thread, _prio))
        throw SystemException("cannot set thread priority");
}
  • 不难看出,这边就是常用的创建线程的方法。

猜你喜欢

转载自blog.csdn.net/fzuim/article/details/78709111