上篇文章咱们简单的理解了浏览器的相关进程,以及各类进程模式,那么这篇文章咱们就探究进程之间的协做吧,可能内容有些多,我能够拆碎一些,可是这不是水文章哦~
chrome
这个实际上是一个老生常谈的问题,听说咱们CTO之前就很喜欢问这个...既然这样那咱们再来从新梳理一下。浏览器
说实话,这个地方的资料真的有些难找,只能逼着我找源码了,简单的说一下吧,否则我怎么装....要是有大神,请指教~,这里代码太多,没兴趣的同窗能够直接看总结。markdown
chrome_exe_main.cc
这个文件是Chrome的启动文件,一个是加载chrome.dll内核文件,检查版本更新,初始化崩溃上报网络
const wchar_t* dll_name = L"chrome.dll";
#if defined(GOOGLE_CHROME_BUILD)
google_update::GoogleUpdateClient client;
client.Init(L"{8A69D345-D564-463c-AFF1-A69D9E530F96}", dll_name);
InitCrashReporter(client.GetDLLPath());
复制代码
chrome_dll_main.cc
在这个文件是能够看到chrome.dll
的入口函数是ChromeMain
函数
DLLEXPORT int __cdecl ChromeMain(HINSTANCE instance, sandbox::SandboxInterfaceInfo* sandbox_info, TCHAR* command_line, int show_command) 复制代码
在这个文件中我发现了一些对进程的处理oop
extern int BrowserMain(CommandLine &, int, sandbox::BrokerServices*);
extern int RendererMain(CommandLine &, int, sandbox::TargetServices*);
extern int PluginMain(CommandLine &, int, sandbox::TargetServices*);
...
if (single_process)
RenderProcessHost::set_run_renderer_in_process(true);
...
...
if (process_type.empty()) {
file_state = logging::DELETE_OLD_LOG_FILE;
}
int rv;
if (process_type == switches::kRendererProcess) {
rv = RendererMain(parsed_command_line, show_command, target_services);
} else if (process_type == switches::kPluginProcess) {
rv = PluginMain(parsed_command_line, show_command, target_services);
} else if (process_type.empty()) {
int ole_result = OleInitialize(NULL);
DCHECK(ole_result == S_OK);
rv = BrowserMain(parsed_command_line, show_command, broker_services);
OleUninitialize();
} else {
NOTREACHED() << "Unknown process type";
rv = -1;
}
if (!process_type.empty()) {
ResourceBundle::CleanupSharedInstance();
复制代码
综上,咱们不难看出,ChromeMain一开始作了一些初始化的操做,不一样类型的进程启动入口都经过ChromeMain来统一处理。其中主要是browser、render还有plugin的进程。post
我感受这个问题可能会很常见,那咱们就经过一个用户正常打开浏览器以后的操做来进行分析吧。渲染进程除外,通熟的说是除了tab以外,有不少交互操做用是浏览器的主进程(Browser process)来处理,咱们比较常见的有:学习
- UI thread : 控制浏览器上的按钮及输入框;
- network thread: 处理网络请求,从网上获取数据;
- storage thread: 控制文件等的访问;
当咱们在地址栏中输入一个地址以后,首先起做用的是UI线程(UI thread)。咱们输入的地址千奇百怪,但正常的来讲绝大部分确实也是URL,但这个是须要UI thread进行判断的。ui
首先他会分析这个URI是什么,若是是http相关会进行DNS查询等,而后直接调用http相关的模块。但也有多是一个搜索地址。this
Browser* StartupBrowserCreatorImpl::OpenTabsInBrowser(Browser* browser, bool process_startup, const StartupTabs& tabs) {
DCHECK(!tabs.empty());
if (!profile_ && browser)
profile_ = browser->profile();
bool first_tab = true;
ProtocolHandlerRegistry* registry = profile_ ?
ProtocolHandlerRegistryFactory::GetForBrowserContext(profile_) : NULL;
for (size_t i = 0; i < tabs.size(); ++i) {
// We skip URLs that we'd have to launch an external protocol handler for.
// This avoids us getting into an infinite loop asking ourselves to open
// a URL, should the handler be (incorrectly) configured to be us. Anyone
// asking us to open such a URL should really ask the handler directly.
bool handled_by_chrome = ProfileIOData::IsHandledURL(tabs[i].url) ||
(registry && registry->IsHandledProtocol(tabs[i].url.scheme()));
if (!process_startup && !handled_by_chrome)
continue;
int add_types = first_tab ? TabStripModel::ADD_ACTIVE :
TabStripModel::ADD_NONE;
add_types |= TabStripModel::ADD_FORCE_INDEX;
if (tabs[i].is_pinned)
add_types |= TabStripModel::ADD_PINNED;
NavigateParams params(browser, tabs[i].url, ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
params.disposition = first_tab ? WindowOpenDisposition::NEW_FOREGROUND_TAB
: WindowOpenDisposition::NEW_BACKGROUND_TAB;
params.tabstrip_add_types = add_types;
#if BUILDFLAG(ENABLE_RLZ)
if (process_startup && google_util::IsGoogleHomePageUrl(tabs[i].url)) {
params.extra_headers = rlz::RLZTracker::GetAccessPointHttpHeader(
rlz::RLZTracker::ChromeHomePage());
}
#endif // BUILDFLAG(ENABLE_RLZ)
Navigate(¶ms);
first_tab = false;
}
if (!browser->tab_strip_model()->GetActiveWebContents()) {
// TODO(sky): this is a work around for 110909. Figure out why it's needed.
if (!browser->tab_strip_model()->count())
chrome::AddTabAt(browser, GURL(), -1, true);
else
browser->tab_strip_model()->ActivateTabAt(0);
}
browser->window()->Show();
return browser;
}
复制代码
综合上边的理解,实际上的流程以下:
下一篇文章咱们就详细的来讲说,浏览器从发出请求到收到请求以及处理的流程~