对于跨平台的应用程序设计,考虑的东西一般都需要比较多,比如线程的设计,在Windows平台和Linux平台就是不一样的API,要适应这两种平台,就需要把这两种API接口通过封装成统一的编程接口,做这样工作的任务也是比较艰难的,因为需要不断地在两个系统上测试。由于Apache基金软件里有这样的共享库,就不必自己再去开发一套,使用现成的Apache软件既提高了开发效率,又可以保证跨平台运行。下面就来分析一下第二人生里是怎么样利用Apache运行库线程的。
#001 LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
#002
mPaused(FALSE),
#003
mName(name),
#004
mAPRThreadp(NULL),
#005
mStatus(STOPPED)
#006 {
#007
// Thread creation probably CAN be paranoid about APR being initialized, if necessary
#008
if (poolp)
#009
{
#010
mIsLocalPool = FALSE;
#011
mAPRPoolp = poolp;
#012
}
#013
else
#014
{
#015
mIsLocalPool = TRUE;
#016
apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
#017
}
#018
mRunCondition = new LLCondition(mAPRPoolp);
#019 }
LLThread类就是第二人生里的线程类,它的主要工作就是调用Apache运行库的线程来工作。上面构造函数里,调用apr_pool_create函数来创建缓冲区。
#001
#002 void LLThread::start()
#003 {
#004
apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
#005
#006
// We won't bother joining
#007
apr_thread_detach(mAPRThreadp);
#008 }
在线程LLThread类的start函数主要用来创建线程,它是调用Apache运行库函数apr_thread_create来创建。在这个函数里,staticRun是线程运行函数,this是传送给staticRun的参数。
#001 //
#002 // Handed to the APR thread creation function
#003 //
#004 void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap)
#005 {
#006
LLThread *threadp = (LLThread *)datap;
#007
#008
// Set thread state to running
#009
threadp->mStatus = RUNNING;
#010
#011
// Run the user supplied function
#012
threadp->run();
#013
#014
llinfos << "LLThread::staticRun() Exiting: " << threadp->mName << llendl;
#015
#016
// We're done with the run function, this thread is done executing now.
#017
threadp->mStatus = STOPPED;
#018
#019
return NULL;
#020 }
LLThread类里的staticRun函数是线程运行主函数,首先获取线程类对象,然后设置线程为运行状态,接着调用函数线程类的run函数作通用工作处理,最后设置线程为停止状态。
#001 // virtual function overridden by subclass -- this will be called when the thread runs
#002
virtual void run(void) = 0;
由于线程类的run函数是纯虚函数声明,就知道LLThread类仅是一个接口类,它是不能创建对象出来的,只能继承它创建完整的功能类。