浅析领导者跟随者线程模型
来源:互联网 发布:刘美麟因为爱情网络 编辑:程序博客网 时间:2024/06/06 18:41
领导者跟随者线程模型是一种经典的线程模型。首先我们来看看什么是领导者和跟随者线程模型,这种模型是怎么定义的。下面给出定义:在该模型中,存在一个领导者线程,处理主要的业务逻辑,比如从socket上读取数据。主要的业务逻辑处理完成后,领导者线程将降级,并且负责选择新的领导者线程。当降级的线程把剩余的业务逻辑完成后,将自动回归线程池,变为跟随者。等待下一次被领导者选中。
在ACE(Adaptive Communication Environment)中,提供了一种实现,下面对这种实现进行源码级的分析。
我们针对主要逻辑进行分析,看看线程池是如何对领导者和跟随者进行切换的。先来看看线程池的线程方法的实现:
int LF_ThreadPool::svc (void)
{
ACE_TRACE (ACE_TEXT ("LF_ThreadPool::svc"));
while (!done ())
{
任何一个跟随者线程都会阻塞在这个方法上,直到自己有机会变成领导者,才会解除阻塞,该方法会放在后面进行分析。
become_leader ();
这段代码很简单,当跟随者线程变成领导者后,负责处理主要逻辑,就是从队列里获取消息。如果取消息失败,新的领导者将被选取,该线程退化为跟随者。
ACE_Message_Block *mb = 0;
ACE_Time_Value tv (LONG_TIME);
tv += ACE_OS::gettimeofday ();
// Get a message, elect new leader, then process message.
if (this->getq (mb, &tv) < 0)
{
if (elect_new_leader () == 0)
break;
continue;
}
在领导者线程处理完主要逻辑后,负责选取新的领导者。该方法也将在后面作出详细分析。
elect_new_leader ();
领导者线程降级,处理生下来的业务逻辑,处理完之后,变成跟随者线程。
process_message (mb);
}
return 0;
}
接下来,我们会对前面涉及的两个主要方法作出分析。
int LF_ThreadPool::become_leader (void)
{
ACE_TRACE (ACE_TEXT ("LF_ThreadPool::become_leader"));
ACE_GUARD_RETURN
(ACE_Thread_Mutex, leader_mon, this->leader_lock_, -1);
if (leader_active ())
{
创建一个新的跟随者对象,里面包含一个条件变量,用于同步。
Follower *fw = make_follower ();
{
如果存在领导者,跟随者线程暂时不能升级为领导者,所以先在这里等待机会。
while (leader_active ())
fw->wait ();
}
一旦跟随者有机会升级为领导者,将删除这个用于同步的领导者对象。防止内存泄露,此时已经不再需要这个对象了。
delete fw;
}
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Becoming the leader/n")));
最后将自己升级为领导者
leader_active (ACE_Thread::self ());
return 0;
}
下面一个方法是领导者的选取方法。先介绍创建跟随者的方法。
这个方法很简单,从堆中申请一个跟随者对象,然后放入队列即可,采用了生产者和消费者模式。
Follower* LF_ThreadPool::make_follower (void)
{
ACE_TRACE (ACE_TEXT ("LF_ThreadPool::make_follower"));
ACE_GUARD_RETURN
(ACE_Thread_Mutex, follower_mon, this->followers_lock_, 0);
Follower *fw;
ACE_NEW_RETURN (fw, Follower (this->leader_lock_), 0);
this->followers_.enqueue_tail (fw);
return fw;
}
接下来介绍主要的方法
int LF_ThreadPool::elect_new_leader (void)
{
ACE_TRACE (ACE_TEXT ("LF_ThreadPool::elect_new_leader"));
ACE_GUARD_RETURN
(ACE_Thread_Mutex, leader_mon, this->leader_lock_, -1);
leader_active (0);
首先判断队列是否为空,如果为空,表示已经没有空闲资源在线程池中,这里可以优化一下,采用自适应的方式创建回收线程池中的线程。
if (!followers_.is_empty ())
{
ACE_GUARD_RETURN (ACE_Thread_Mutex,
follower_mon,
this->followers_lock_,
-1);
从队列中获取一个跟随者
Follower *fw;
if (this->followers_.dequeue_head (fw) != 0)
return -1;
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) Resigning and Electing %d/n"),
fw->owner ()));
通知该跟随者,目前你有机会变成领导者啦!恭喜恭喜……
return (fw->signal () == 0) ? 0 : -1;
}
else
{
ACE_DEBUG
((LM_ERROR, ACE_TEXT ("(%t) Oops no followers left/n")));
return -1;
}
}
总结:
利用该线程模型,可以用在网络应用程序开发中,领导者负责从socket上读取数据,这个作为领导者的主要逻辑,之后让出领导者的权限,数据的处理作为该线程成为跟随者线程前应该处理的逻辑。线程池可以设计成自适应的,池中线程的数量可以根据当时的业务负载自动调整。
- 浅析领导者跟随者线程模型
- 浅析领导者跟随者线程模型
- Leader/Follower 领导者/跟随者线程模型
- 线程池模式比较-------ICE线程池模型------L/F领导者跟随者模式
- 线程池模式比较-------ICE线程池模型------L/F领导者跟随者模式
- 线程池模式比较-------ICE线程池模型------L/F领导者跟随者模式
- 线程池模式比较-------ICE线程池模型------L/F领导者跟随者模式
- 线程池模式比较-------ICE线程池模型------L/F领导者跟随者模式
- 线程池模式比较-------ICE线程池模型------L/F领导者跟随者模式
- ICE线程池模型 — L/F领导者跟随者模式
- 领导者/跟随者模式
- ACE 领导者-跟随者线程池 选举方案
- UNIX网络编程——线程池模式比较(ICE线程池模型和L/F领导者跟随者模式)
- 简化版的LF线程池(领导者与跟随者模式)
- 线程池模式举例:HS/HA 半同步/ 半异步模式与L/F 领导者跟随者模式
- 线程池模型:领导者/追随者 半同步/半异步模型
- 浅析Android线程模型
- 浅析Android线程模型
- SimpleTag_TFIDF
- ASP.NET与ASP的区别(续)
- MR-eclipse本地开发环境搭建&Hadoop学习总结
- 注销对话作用域的上下文变量
- 【学习】ListView子控件的监听及刷新数据不变
- 浅析领导者跟随者线程模型
- SimpleTag_TFIDF++
- TCP
- 招聘之面试流程总结_针对具有一定研发经历的求职者
- hdu 4240 Route Redundancy(最大流)
- 写给想当程序员的朋友
- 改进版截图函数(主要解决XP下保存对话框遮挡截图问题)
- LIRE代码剖析2——Index和Search代码解析
- poj2387