解释“领导者/追随者”模式

时间:2010-06-17 01:08:31

标签: design-patterns concurrency

我似乎无法找到“领导/追随者”模式的良好且易于理解的解释。所有解释都只是refer to it in the context of some problemare completely meaningless

任何人都可以向机制解释这种模式的工作原理,以及为什么以及如何通过更传统的异步IO模型提高性能?图表的示例和链接也很受欢迎。

5 个答案:

答案 0 :(得分:66)

正如您可能已经读过的那样,该模式由4个组件组成:ThreadPool,HandleSet,Handle,ConcreteEventHandler(实现EventHandler接口)。

你可以把它想象成一个出租车站,晚上所有司机都在睡觉,除了一个,领导者。 ThreadPool是一个管理许多线程的工作站 - cabs。

领导者正在等待HandleSet上的IO事件,就像驱动程序如何等待客户端一样。

当客户到达时(以识别IO事件的句柄形式),领导者司机唤醒另一名司机成为下一位领导者,并提供其乘客的请求。

当他将客户带到指定地址(称为ConcreteEventHandler并将Handle移交给它)时,下一位领导可同时为另一位乘客提供服务。

当司机结束时,他将出租车带回车站,如果车站不是空的话就会睡着。否则他就成了领导者。

这种模式的优点是:

  • 线程之间没有通信是必要的,没有同步, 也没有共享内存(没有锁,互斥) 需要。
  • 可以添加更多ConcreteEventHandlers而不会影响任何其他 事件处理程序
  • 因多线程而最小化延迟

缺点是:

  • 复杂
  • 网络IO可能成为瓶颈

答案 1 :(得分:2)

我想通过链接来自同一作者的另一个PDF来添加Jake的答案,该PDF详细说明了他们选择Leader / Follower模式而不是其他选择的用例: http://www.dre.vanderbilt.edu/~schmidt/PDF/OM-01.pdf

答案 2 :(得分:2)

大多数人都熟悉经典的模式,每个请求使用一个线程。可以如下图所示。服务器维护一个线程池,并为每个传入请求分配一个负责处理该线程的线程。

enter image description here

领导者/跟随者模式中,这些线程之一被指定为当前领导者。该线程负责侦听多个连接。收到请求时:

  • 首先,该线程通知队列中的下一个(跟随者)线程,该线程成为新的领导者并开始侦听新的请求
  • 然后,线程继续处理先前收到的请求。

下图说明了它是如何工作的。

enter image description here

与“每个请求一个线程”模式相比,“领导者/跟随者”模式可以更有效地利用资源,尤其是在具有大量并发连接的情况下。这是由于以下事实:每个请求一个线程将需要为每个连接使用单独的线程,这非常昂贵,这使得在某些资源有限的情况下不可行。

与其他技术相比,以下论文对模式和优点/缺点进行了更全面的分析:http://www.kircher-schwanninger.de/michael/publications/lf.pdf

答案 3 :(得分:0)

答案 4 :(得分:0)

我认为最“亲自动手”的例子是phusian乘客和铁路应用程序。 (一种误导性乘客实际上是一个mod_rails apache进程,管理许多正在睡觉/停放的ruby应用程序。)

所以你开发了一个rails应用程序或sinatra应用程序。然后将其部署在安装了乘客的网络服务器上。

领导者实际上是乘客负载均衡器。 乘客是访问网页的人。 出租车是乘客设备池中的轨道应用程序的休眠实例。

将此池设置为45(rails应用程序中的database.yml)。你说我想要45辆出租车准备好为网页提供服务。 当有人访问虚拟主机时,乘客会将请求委托给45个等待的应用程序中的一个。应用程序不必彼此通信,因为它们都连接到同一个数据库后端(如果您复制数据,也可以连接多个)。

http://www.modrails.com/

很酷的是,尽管单独的进程可能需要一段时间才能处理请求,但整个系统确实非常高效/快速,因为您有45个已准备好处理请求。因此,即使第一辆出租车(轨道应用程序)没有从它的骑行回来(服务于请求的页面),第二个等待的实例也可以用于下一个请求。第一次完成后它也会回到队列中,这样你就可以快速响应并轻松获得4000+ pagereq./sec,即使单个rails应用程序只能处理400req / sec。当然有限制(池大小的内存等,否则你可以采用200000 rails应用程序的poool大小)但实际上这很好用......