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

最终执行的方法如下



HHVM源码剖析的更多相关文章
- jQuery之Deferred源码剖析
一.前言 大约在夏季,我们谈过ES6的Promise(详见here),其实在ES6前jQuery早就有了Promise,也就是我们所知道的Deferred对象,宗旨当然也和ES6的Promise一样, ...
- Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现
声明:本文为原创博文,转载请注明出处. Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们.在网络编程中,一般都是基于Reactor线程 ...
- Apache Spark源码剖析
Apache Spark源码剖析(全面系统介绍Spark源码,提供分析源码的实用技巧和合理的阅读顺序,充分了解Spark的设计思想和运行机理) 许鹏 著 ISBN 978-7-121-25420- ...
- 基于mybatis-generator-core 1.3.5项目的修订版以及源码剖析
项目简单说明 mybatis-generator,是根据数据库表.字段反向生成实体类等代码文件.我在国庆时候,没事剖析了mybatis-generator-core源码,写了相当详细的中文注释,可以去 ...
- STL"源码"剖析-重点知识总结
STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...
- SpringMVC源码剖析(四)- DispatcherServlet请求转发的实现
SpringMVC完成初始化流程之后,就进入Servlet标准生命周期的第二个阶段,即“service”阶段.在“service”阶段中,每一次Http请求到来,容器都会启动一个请求线程,通过serv ...
- 自己实现多线程的socket,socketserver源码剖析
1,IO多路复用 三种多路复用的机制:select.poll.epoll 用的多的两个:select和epoll 简单的说就是:1,select和poll所有平台都支持,epoll只有linux支持2 ...
- Java多线程9:ThreadLocal源码剖析
ThreadLocal源码剖析 ThreadLocal其实比较简单,因为类里就三个public方法:set(T value).get().remove().先剖析源码清楚地知道ThreadLocal是 ...
- JS魔法堂:mmDeferred源码剖析
一.前言 avalon.js的影响力愈发强劲,而作为子模块之一的mmDeferred必然成为异步调用模式学习之旅的又一站呢!本文将记录我对mmDeferred的认识,若有纰漏请各位指正,谢谢.项目请见 ...
随机推荐
- 一个高性能异步socket封装库的实现思路 (c#)
前言 socket是软件之间通讯最常用的一种方式.c#实现socket通讯有很多中方法,其中效率最高就是异步通讯. 异步通讯实际是利用windows完成端口(IOCP)来处理的,关于完成端口实现原理, ...
- ndk-stack使用方法
最近在mac上编译android 版本,各种崩溃让人蛋疼,网上学习了下ndk-stack使用方法. 自己备忘下: 1.运行终端. 跳转到你android sdk 目录 因为你的adb 在里面. 如 c ...
- Flash真的老了,HTML5将取代其地位
简单讲一些网页开发的趋势吧! Flash老了 Flash是一个落后于时代的技术,靠对客户端的高资源占用率来获取传输过程的低带宽占用. Flash不再安全 Flash是一个落后于时代的技术,靠对客户端的 ...
- GDI+ 应用,Release没有错误,Debug很多。
问题描述: 在VC6环境中,一个界面工程利用了GDI+的一些库,Release模式下编译.运行无误,但在Debug模式下就会报告错误. xxx.cpp D:\Program Files\Microso ...
- NYOJ 2357: 插塔憋憋乐 贪心
2357: 插塔憋憋乐 时间限制: 1 Sec 内存限制: 128 MB 提交: 82 解决: 18 [提交][状态][讨论版] 题目描述 众所不知,LLM是一位红警3大佬,打的非常厉害,但是曾经 ...
- Python--Pycharm backup_ver1.py 控制台一直Backup FAILED
1.windows不自带zip,需自行安装,http://gnuwin32.sourceforge.net/packages/zip.htm 2.安装后,要配置环境变量:PATH 3.简明Python ...
- 【Cocos游戏实战】功夫小子第七课之游戏主功能场景逻辑功能和暂停功能场景的分析和实现
CSDN的markdown编辑器是吃屎了么! !.什么玩意.!写了一半写不了东西还全没了,搞个毛线! 本节课的视频教程地址是:第七课在此 假设本教程有帮助到您,希望您能点击进去观看一下,并且如今注冊成 ...
- hdu 1885 Key Task(bfs)
http://acm.hdu.edu.cn/showproblem.php?pid=1885 再贴一个链接http://blog.csdn.net/u013081425/article/details ...
- C++学习笔记24,方法重写与方法隐藏
该博文仅用于交流学习.请慎用于不论什么商业用途.本博主保留对该博文的一切权利. 博主博客:http://blog.csdn.net/qq844352155 转载请注明出处: 方法重写.是指在子类中又一 ...
- 深入了解MyBatis返回值
深入了解MyBatis返回值 想了解返回值,我们须要了解resultType,resultMap以及接口方法中定义的返回值. 我们先看resultType和resultMap resultType和r ...