专栏首页magicsoarHHVM源码剖析

HHVM源码剖析

一、前言

hhvm源码中充满了很多C++11的新特性,并且使用了各种设计模式如工厂,模板方法等,利用智能指针包裹指针,让delete没有肆意的出现

模板,继承,explicit,纯虚函数的出现令代码中充满了惊喜

例如下面这段代码:run_函数是pthread_create执行的函数

二、hhvm启动流程总览

hhvm/main.cpp

75行:调用execute_program函数进行具体的逻辑

runtime/base/program-functions.cpp 

885行:调用execute_program_impl进行具体的逻辑

runtime/base/program-functions.cpp 

1260:  从配置文件中加载配置项

1475:函数负责启动线程与接收处理请求

总体流程图如下:

RuntimeOption::Load函数负责加载配置文件中的配置项

start_server函数负责启动线程与接收处理请求

三、Load函数配置文件的加载与处理

以如下配置项的解析为例

Server{ Type= FastCGIServer ThreadCount=20 ###...... }

runtime/base/runtime-option.cpp

782-801行 解析配置文件中Server块中的内容

787行 将配置文件中的type值FastCGIServer赋值给ServerType

800行 将配置文件中的ThreadCount赋值给ServerThreadCount

所以ServerType的值为FastCGIServer

ServerThreadCount的值为20

四、start_server初始化HttpServer对象

runtime/base/program-functions.cpp 

799行  初始化HttpServer对象

837行 启动server,接受处理请求

httpserver对象的初始化函数

runtime/server/http-server.cpp 

88行 KNumProcessors为系统内核的个数,通过62行的 const int kNumProcessors = sysconf(_SC_NPROCESSORS_ONLN);获得

84-90行:如果配置的thread大于系统的内核的个数,则在启动时只启动与系统内核个数相同的thread数,将其余的个数赋值给additionalThreads

92行:调用工厂函数,针对ServerType:FastCGIServerc生成一个工厂对象

96-101行:将配置文件中的信息赋值给options对象,注意这里的startingThreadCount最大为系统内核的个数

102行:根据options配置信息生成一个Server

runtime/server/fastcgi/fastcgi-server-factory.cpp 

听过FastCGIServerFactory工厂生成一个FastCGIServer对象

FastCGIServer的构造函数

runtime/server/fastcgi/fastcgi-server.cpp  

这里的worker就是启动的线程数目

这里关注一下m_dispatcher的初始化

runtime/server/fastcgi/fastcgi-server.h 

JobQueueDispatcher<FastCGIWorker> m_dispatcher;   

m_dispatcher的类型为JobQueueDispatcher

FastCGIWorker的定义如下:

typedef ServerWorker<std::shared_ptr<FastCGIJob>,FastCGITransportTraits> FastCGIWorker;

struct ServerWorker  : JobQueueWorker<JobPtr,Server*,true,false,JobQueueDropVMStack>{}//传入的第三个参数为true

template<typename TJob, typename TContext = void*, bool countActive = false, bool waitable = false, class Policy = detail::NoDropCachePolicy>  class JobQueueWorker {}

ServerWorker的继承关系如下

所以这里的countActive为true

467-473行:由于CountActivewe== true所以不会进入下方的逻辑中

util/job-queue.h

656-658行 同样由于CountActive== true 因此不会走入656-658行里面

五、start_server RunOrExitProcess启动一个Server

runtime/server/http-server.cpp 

262-268行 由于没有配置 ThreadDocuments,ThreadLoopDocuments所以size()大小为0 不会走入

269行 ServerPort的初始化值为80,只要配置文件中的Port值不为0(即使配置文件中没有Server.Port值,也会初始化为80) 就会走入

runtime/base/runtime-option.cpp

121 int RuntimeOption::ServerPort = 80; 

相比之下

AdminServer.Port的值初始化为0

runtime/base/runtime-option.cpp

266 int RuntimeOption::AdminServerPort = 0; 

因此只有配置了才会启动AdminServer

runtime/server/http-server.cpp

非AdminServer的时候 传入的pageServer==true因为走入579行

这里的m_pageServer为fastcgi-server对象

runtime/server/fastcgi/fastcgi-server.cpp 

263行 m_worker.start()通过C++11的thread启动一个线程负责网络IO

264行 m_dispatcher.start() 通过pthread_create启动若干线程负责CPU部分

下面看一看m_dispatcher.start的详细逻辑

util/job-queue.h  

513-516行 如果配置的threadCount过小的话 这里会进行增加

517-520行 通过start()函数创建线程

util/job-queue.h 

util/async-func.h 

AsyncFunc继承自AsyncFuncImpl

AsnycFuncImpl实现了start()函数

util/async-func.cpp

至此线程启动完毕,线程运行的函数为ThreadFunc

六、ThreadFunc从何而来

ThreadFunc是从那里来的呢?

util/async-func.cpp

这里使用了模板方法设计模式

util/async-func.h

一段神奇的代码.....

util/job-queue.h

最终执行的方法如下

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Effective Modern C++翻译(3)-条款2:明白auto类型推导

    条款2 明白auto类型推导 如果你已经读完了条款1中有关模板类型推导的内容,那么你几乎已经知道了所有关于auto类型推导的事情,因为除了一个古怪的例外,aut...

    magicsoar
  • Effective Modern C++翻译(6)-条款5:auto比显示的类型声明要更好

        在概念上说,auto关键字和它看起来一样简单,但是事实上,它要更微妙一些的。使用auto会让你在声明变量时省略掉类型,同时也会防止了手动类型声明带来的正...

    magicsoar
  • mysql复制

    一、复制的意义 mysql的复制功能是构建基于MySql大规模,高性能应用的基础,我们可以通过为服务器配置一个或多个备库来进行数据同步;复制功能不仅有利于构建高...

    magicsoar
  • Nginx限制连接数和请求数

    其中limit_req_conn模块可以根据源IP限制单用户并发访问的连接数或连接到该服务的总并发连接数

    拓荒者
  • RHEL7及CentOS7中让指定用户才能su到root-系统管理(3)

    在默认情况下,任何普通用户都能通过su命令切换到root用户。众所周知,root对于系统拥有至高无上的权限!因此,任何用户不在允许范围内切换到root都会威胁着...

    耕耘实录
  • 【TS】358- 浅析 TypeScript 设计模式

    设计模式就是软件开发过程中形成的套路,就如同你在玩lol中的“正方形打野”,“四一分推”,又或者篮球运动中的“二夹一”,“高位单打”一样,属于经验的总结。

    pingan8787
  • 重新GEOmetadb分析发现seq技术实验终于超过array技术啦

    比较芯片领域 Affymetrix 公司一家独大,可惜现在也被赛默飞收购了,但其实我开始从事生物信息学的时候已经是ngs技术的天下了,只不过数据处理到发表文章通...

    生信技能树
  • 网络工程师进阶 | 我不常用的命令以及不经常注意的地方—交换部分

    SVI接口的ACL只能对穿越该SVI接口的流量进行控制,要改变相应VLAN中的流量必须使用VACL

    网络技术联盟站
  • 【每周一库】 see - An HTTP server for hosting static files

    see是一个静态文件的HTTP服务器,它的Github仓库介绍十分简单,包含的特性有

    MikeLoveRust
  • WordPress插件开发教程二:创建插件菜单和插件设置页面

    如果我们的插件设置很简单,只需一个或两个参数的时候,可以考虑添加到设置->常规的页面中,这样就无须再新增页面了

    沈唁

扫码关注云+社区

领取腾讯云代金券