wpcockroach

导航

统计

Theron, a lightweight C++ concurrency library, 源码分析(一)

Theron是一个基于Actor Model的轻量级C++并行库(Theron is a fast, portable, lightweight C++ concurrency library based on Actor Model)。

在分析Theron源代码前,先简单说一说Actor Model到底是一个什么东西。

Actor Model

Actor Model是一种并发模型,详细的信息你可以在wiki上找到。如果你觉得英文比较难理解,也可以看看老赵的博客,他写了3篇关于Actor Model的博文(123)。可以说,看完这三篇文章,你应该能够对Actor Model建立一个直观的认识。

我个人觉得并行编程的模型强调了一点,不要使用简单的线程来解决并发的问题,因为不容易处理好锁与锁之间的关系。要从整体业务上来考虑问题,以一个一个关联不是很紧密的流程为基础来进行并发。也就是说,以task为基础进行并发。

说到这,前戏算是完了,我们进入正题。。。。

在Theron中,或者说在Actor Model中有几个重要的概念,它们分别是:

  • Actor
  • Message
  • Address
  • Mailbox

Actor就不多说了。在Actor Model中,万事万物皆actor。和面向对象中强调万事万物皆对象是一样的。

Message就是消息吧。在Actor Model中,actor与actor之间通过消息进行通信。那么actor如何将指定的消息发送给它想通知的其他actor呢?靠Address。

Address就是地址,更严格地说是mailbox的地址。Actor和actor只能通过地址相互通信。因此,如果两个actors相互不知道对方的地址,那么它们就无法相互发送消息。接收消息的actor可以从message中提取到发信actor的地址。

Mailbox就是邮箱,用来存放收到的消息。

所以,Actor Model可以形象地理解成人和人之间相互寄信。人就是actor,信就是message,家庭地址就是address,邮箱就是mailbox,信封上有寄信人的地址。也正因为这种类比,我们可以想象:

  • 不同actor之间是并行执行的
  • Actor可以顺序执行收到的消息,也可以并行执行。一般来说,顺序执行比较容易实现

在Theron中,除了上面4个重要的类之外,还有一个类也很重要,就是Framework类。事实上他有点像邮局。

既然Theron是一个并发库,那势必还要有线程相关的类。直接和线程相关的有4个,他们分别是:

  • Thread
  • ThreadContext
  • WorkerThreadStore
  • ThreadPool

间接关联的有一个:

  • ProcessorContext

我们先从线程相关的类开始说起。

Thread and ThreadPool

Thread class

根据运行环境的不同,Theron通过宏定义区别出了3种实现Thread类的方法,分别是:

  • 基于Win32 API的实现
  • 基于boost::thread的实现
  • 基于C++11 std::thread的实现

你要定义一个具体的业务处理函数,该函数会在特定实现中的线程里被调用。

主要的几个成员函数是:

  • Start(EntryPoint entryPoint, void* context)
  • Join

ThreadContext struct

这个结构是ThreadPool中的内部被定义的。所以可以知道它和ThreadPool的关系要比Thread类和ThreadPool的关系来得更紧密。事实上也是这样的。ThreadPool所管理的具体线程事实上是通过ThreadConext来进行的。所以确切地说,线程池中的线程在这里指ThreadContext更恰当些。

先来看下它的具体定义。

   1: struct ThreadContext
   2: {
   3:     WorkerContext* mWorkerContext;
   4:  
   5:     WorkQueue* mWorkQueue;
   6:     uint32_t   mNodeMask;
   7:     uint32_t   mProcessorMask;
   8:     bool       mRunning;
   9:     bool       mStarted;
  10:     Thread*    mThread;
  11: };

这里有2个东西可能比较困惑。一是,WorkerContext;二是,WorkQueue。除此以外,应该没有不难理解的东西。WorkerContext和WorkQueue暂时先搁置下,等讲到ThreadPool线程池的时候我们再来说这两个东西。

ThreadPool class

说到ThreadPool,我想大家应该都不怎么陌生。在操作系统级别都提供了线程池相关的函数。这里需要强调一点的是,Theron中线程池中的线程不是Thread而是ThreadContext。为什么这么说?等到说Framework类的时候,你就更清楚了。

ThreadPool是一个模版类。

   1: template <class WorkQueue, class WorkProcessor, class WorkerContext>
   2: class ThreadPool;

这个类在Framework类中被这样使用:

   1: typedef ThreadSafeQueue<Mailbox> WorkQueue;
   2: typedef ThreadPool<WorkQueue, WorkItem, WorkerThreadStore> ThreadPool;

所以,ThreadContext中的WorkQueue就是ThreadSafeQueue<Mailbox>类型,WorkerContxt就是WorkerThreadStore类型。WorkerThreadStore会在后面介绍,现在你可以认为他是工作线程保存相关信息的一个storage。

ThreadPool提供了几个重要的成员函数。

CreateThread(ThreadContext* threadContext)

创建一个Thread对象并把句柄保存到threadContext->mThread中。

StartThread(ThreadContext* threadContext, WorkQueue* workQueue, …)

启动线程。总共4个参数,这里罗列了前两个最重要的。

StartThread将workQueue保存到threadContext->mWorkQueue中,然后通过threadContext->mThread->Start启动线程,在线程中处理workQueue中的mailbox。

传递给Start函数的第一个参数EntryPoint是这样定义的:

   1: void ThreadEntryPoint(void* context)
   2: {
   3:     ThreadContext* threadContext(reinterpret_cast<ThreadContext*>(context));
   4:  
   5:     threadContext->mStarted = true;
   6:  
   7:     uint32_t backoff(0);
   8:     while (threadContext->mRunning)
   9:     {
  10:         if (typename WorkQueue::ItemType* item = threadContext->mWorkQueu->Pop())
  11:         {
  12:             WorkProcessor::Process(item, threadContext->mWorkerContext);
  13:             backoff = 0;
  14:         }
  15:         else
  16:         {
  17:             Utils::Backoff(backoff);
  18:         }
  19:     }
  20: }

ItemType就是Mailbox。WorkProcessor在这里是WorkItem类。至于WorkItem::Process到底做了什么事情,还是留等后面我们对Theron了解更深入了之后再进行深入分析。这里你只要知道线程池道理这里就是逐一处理Mailbox里的信息了。

另外,这里还要注意的一个点是这里的while是一个死循环。所以当线程池把线程启动之后,除非特定操作,不然这个线程是不会退出的。

线程池类还提供了StopThread和DestroyThread两个函数,这里就不多做介绍了。

WorkerThreadStore and ProcessorContext

这两个结构放到后面再议。

说完了线程相关的内容,我们开始介绍Theron中和Actor Model概念有密切联系的几个类。先说Framework。

先到这里。。。未完待续。。。

posted on 2012-12-03 22:43  wpcockroach  阅读(2948)  评论(0编辑  收藏