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 ;
class Foundation_API Runnable
{
public :
Runnable ();
virtual ~Runnable();
virtual void run() = 0 ;
};
}
自定义的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" );
}