hhvm源碼中充滿了不少C++11的新特性,而且使用了各類設計模式如工廠,模板方法等,利用智能指針包裹指針,讓delete沒有肆意的出現設計模式
模板,繼承,explicit,純虛函數的出現令代碼中充滿了驚喜網絡
例以下面這段代碼:run_函數是pthread_create執行的函數async
2、hhvm啓動流程總覽
hhvm/main.cpp函數
75行:調用execute_program函數進行具體的邏輯oop
runtime/base/program-functions.cpp 源碼分析
885行:調用execute_program_impl進行具體的邏輯post
runtime/base/program-functions.cpp spa
1260: 從配置文件中加載配置項線程
1475:函數負責啓動線程與接收處理請求設計
整體流程圖以下:
RuntimeOption::Load函數負責加載配置文件中的配置項
start_server函數負責啓動線程與接收處理請求
3、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
4、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行裏面
5、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()函數