第二人生的源码分析(四十一)使用Apache运行库线程
对于跨平台的应用程序设计,考虑的东西一般都需要比较多,比如线程的设计,在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类仅是一个接口类,它是不能创建对象出来的,只能继承它创建完整的功能类。