Chinaunix首页 | 论坛 | 博客
  • 博客访问: 432232
  • 博文数量: 43
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 518
  • 用 户 组: 普通用户
  • 注册时间: 2015-12-14 12:10
个人简介

邮箱:oxwangfeng@qq.com

文章分类

全部博文(43)

文章存档

2021年(1)

2018年(7)

2017年(9)

2016年(26)

我的朋友

分类: 服务器与存储

2016-02-01 10:49:09


EventProcessor

EventProcessor类是模型的核心组件。它负责创建和管理若干组thread,这些thread用于在给定时间内或周期性地异步执行用户定义的任务。EventProcessor提供了一组调度函数,通过这些调度函数可以指定它的一个线程来回调continuation。这些函数调用是非阻塞的。相反,它们返回一个Event对象,并在随后或一个特定时间安排contination的回调。EventEventProcessor来分配和释放。状态机可以访问返回的,非递归的事件,直到事件被取消或事件的回调函数完成。对于递归的eventevent只有在被取消之后才会被访问。对event完成或被取消,eventProcessor负责释放它。

Processor创建若干组Thread,并将Event按类型调度到相应的ThreadEvent队列上,Thread通过执行Event对应的Continuation中的回调函数,来完成状态的迁移。从初始态到终止态的迁移代表了整个事件的执行过程,而Thread是永不退出的,等待着下一个事件的到来。

EThread

Ethread类是由Event系统创建和管理的thread类型。它在event系统中是一个可以用来调度event的接口(其他两个是EventEventProcessor类)。为了处理event,每个Ethread对象有两个event队列,一个外部和一个内部。外部队列为Ethread的用户提供,并通过它来附加event到该特定thread。外部队列可以同时被别的thread访问,对它的任何操作都必须以原子方式进行处理。另一方面,内部队列只由Ethread使用,用来处理一定时间内的定时event。这些event在内部排队,也可以来自外部队列。

trafficserver创建三种类型的线程:regular(普通)与dedicated(专用)类型、monitor类型。

一个dedicated类型的线程,它在执行完某个continuation后,就消亡了。

 regular类型的线程,在trafficserver启动后,就一直存在着,它的线程执行函数是一个死循环。regular线程维护了一个event pool,当event pool不为空时,线程就从event pool中取出event,同时执行event封装的continuation。当需要调度某个线程执行某个continuation时,通过EventProcessor将一个continuation封装成一个event并将其加入到线程的event pool中。

Event     

trafficserverevent分为以下几种类型:立即执行的event,定时执行的event,定期执行的event以及随时执行的event。一个event类包含一个timeout时间(timeout_at变量),一个period时间(period变量)timeoutperiod没有限制。

            1) timeout等于0,该event是一个立即event

            2) period等于0,该event是一个定时eventtimeout时间到期后event就会执行。

            3) period大于0,该event是一个定期执行的event,每隔period就会执行一次。

            4) 如果period小于0event是一个随时执行的event,当线程执行完其他类型的event后,就会执行这一类event。目前ts只有一种该类型的event,就是epoll,这样在工作线程没有其他任务时就立即执行epoll_wait

 

eventsystem核心代码与数据结构

EThread::execute                      //对应线程执行函数,对于regular类型的线程,是一个死循环

//这一组函数,选择类型与EventType参数值相同的那组线程,从该组线程中以round robin方式选出一个线程,

将event插入到该线程的外部队列中

EventProcessor::schedule_imm          //立即执行event

EventProcessor::schedule_at           //将来某个确定的时间点执行event

EventProcessor::schedule_in           //一段时间以后执行event

EventProcessor::schedule_every        //定期或随时event,根据参数给出的时间是正值还是负值

EThread::schedule_*                   //这一类函数大致与EventProcessor提供的相同

EThread::schedule_*_local             //这一类函数与上面的唯一不同是,将event直接加入内部队列中

Event::schedule_*                     //这一类函数也是将event直接加入到对应线程的内部队列中

 

问题:

1.外部队列和内部队列

EventProcessor,Ethread,Event三者都有队列;其中EventProcessor类只有外部队列,Ethread类有外部队列和内部队列,Event类只有内部队列;外部队列和内部队列所起的作用是什么?

         外部队列的处理分为三中情况,1.立刻执行的事件;2.加入内部队列的事件;3.epoll网络事件;

         内部队列:一般是定时器事件。内部队列采用优先队列实现;优先处理马上到期的event;

 

2.epoll模型的关系

网络模型支持EPOLL,kqueue,port三中网络模型;

这两个函数其实是专为网络模块设计的,一个线程可能一直阻塞在epoll_wait上,通过引入一个pipe或者eventfd,当调度一个线程执行某个event时,异步通知该线程从epoll_wait解放出来。

Execute()EThread线程的默认入口函.

EThread::execute()处理过程: EventQueueExternal 是外部队列,EventQueue是内部队列,NegativeQueuepoll网络事件队列。事件的处理过程是这样的:先从外部队列中取出一个事件e,查看这个事件是否需要立刻执行(通过判断e->timeout_at可以确定是否需要立刻执行),如果需要立刻执行,则调用process_event立刻执行事件。如果取出的事件e,并不是一个需要立刻执行的事件,且不属于poll之类的网络事件,则将这个事件加入到内部队列EventQueue中;如果取出的事件e属于epoll这样的网络事件,则将其加入到NegativeQueue中。外部队列的事件处理完成后,接下来处理内部队列中的事件(这部分事件有刚刚在处理外部事件时加入到内部队列的事件)内部队列EventQueue的实现是用的优先级队列的方式,对于内部队列中已经到期的事件,则执行event.


1.设置continuation函数SET_CONTINUATION_HANDLER(vc, (NetVConnHandler) & UnixNetVConnection::acceptEvent);

2.

外面直接调用EventProcessorEthreadEVENT的调度函数,然后执行上面的continuation函数;

EThread::schedule_in(this, NET_RETRY_DELAY);

EThread::schedule_imm_signal

EventProcessor::schedule_imm_signal

EVENT::schedule_in(NET_RETRY_DELAY);//这个就是类似一个定时事件

网络队列采用NegativeQueue队列,所以需要采用EventProcessor或者EThread的调度函数;如果需要多线程都可以处理这个事件,则选择EventProcessor的调度函数;如果只需要让特定的线程处理这个事件,则选择EThread的调度函数;

         定时执行事件或者定时器事件可以优先选择采用Event的调度函数(也可以使用EventProcessor或者EThread的调度函数,不过最终转换为内部队列,使用Event的调度函数)

 

线程类型:(个数可配置的)

1. accept thread 

         -> CONFIG proxy.config.accept_threads INT 2 

         用两个线程来接受8080服务端口

2. disk io worker thread 

         CONFIG proxy.config.cache.threads_per_disk INT 8

3. epoll_wait thread 

         CONFIG proxy.config.exec_thread.limit INT 2

4. http state worker thread

         CONFIG proxy.config.task_threads INT 2

 

Other help Thread Type-> 这些线程都只有一个,不需要配置。

1. [STAT_SYNC] ->raw-stat syncer

2. [CONF_SYNC] ->config syncer

3. [REM_SYNC] ->remote syncer

4. [LOGGING]     ->log flush

 




阅读(3664) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~