POCO C++库学习和分析 -- 线程 (四) 5. 主动对象 5.1 线程回顾 在讨论主动对象之前,我想先说一下对于Poco 中多线程编程的理解。大家都知道,对于多线程编程而言最基本的元素只有两个数据:锁和线程。线程提高了程序的效率,也带来了数据的竞争,因此为了保证数据的正确性,孪生兄弟"锁"随之产生。 对于不同的操作系统和编程语言而言,线程和锁通常是以系统 API 的方式提供的,不同语言和不同操作系统下API 并不相同,但线程和锁的特性是一致的,这也是对线程和锁进行封装的基础。比如所有的系统线程API 都提供了线程开始函数,其中可以设置线程的入口函数,提供了线程终止等功能。用面对对象的思想对线程和锁进行封装后,线程和锁就可以被看成编程时的一个基本粒子,一堆积木中的一个固定模块,用来搭建更大的组件。 除了线程和锁这两个基本模块之外,定时器和线程池也比较常用。线程池多用作线程频繁创建的时候。在Poco 中,把线程池封装成为一个对象,池中的线程在池存在时始终存活,只不过是线程状态有所不同,不是运行中就是挂起。如果把线程看成一种资源的话,线程资源的申请和释放被放入了线程池的构造和析构函数中,Poco 的这种封装也就是 C++推荐的方法。 在Poco 的线程池实现中,ThreadPool 类还提供了一个线程池的单件接口。这个由静态函数定义: [cpp] view plaincopy 1. static ThreadPool& defaultPool(); 通过这个函数,使用者可以很方便的从 Poco 库中获取一个线程的起点,而无需关心线程维护的细节,这样使用者可以进一步把注意力放在需要实现的业务上。在实现了 ThreadPool 的这个接口后,Poco 类中关于线程的更高级封装即可以实现。如定时器(Timer),主动对象(Activity Object),任务(Task)。 在Poco 实现定时器,实现 ThreadPool 中的PooledThread,以及接下来要讨论的主动对象中的ActiveRunnable,RunnableAdapter,ActiveDispatcher 时,可以发现这些类都从 Runnable 继承。这些类需要实现自己的run 函数,只不过在run 函数中做的工作不同。 定时器中的run 函数工作就是计时,定期更新实现,至触发时刻运行使用者定义的用户事件。而PooledThread 的工作则是,控制线程状态,在挂起和运行间切换,当有用户业务需要运行时,运行用户业务。说穿了这些类都是用户业务的一个代理。只不过代理时,实现的手段不同。 5.2 主动对象 总结了前几章后,让我们继续往下看一下主动对...