最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 浏览器进程之间协作的理解与研究

    正文概述 掘金(Winder)   2021-04-02   668

    上篇文章我们简单的理解了浏览器的相关进程,以及各种进程模式,那么这篇文章我们就探究进程之间的协作吧,可能内容有些多,我可以拆碎一些,但是这不是水文章哦~
    浏览器进程之间协作的理解与研究

    附:历史文章

    进程之间的协作

    当打开浏览器,从输入url到展示页面,发生了什么

    这个其实是一个老生常谈的问题,据说我们CTO以前就很喜欢问这个...既然这样那我们再来重新梳理一下。

    打开浏览器

    说实话,这个地方的资料真的有些难找,只能逼着我找源码了,简单的说一下吧,不然我怎么装....要是有大神,请指教~,这里代码太多,没兴趣的同学可以直接看总结。

    Chrome的启动文件

    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)
    

    在这个文件中我发现了一些对进程的处理

    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的进程。

    从输入url到展示页面,发生了什么

    我感觉这个问题可能会很常见,那我们就通过一个用户正常打开浏览器之后的操作来进行分析吧。渲染进程除外,通熟的说是除了tab之外,有很多交互操作用是浏览器的主进程(Browser process)来处理,我们比较常见的有:

    浏览器进程之间协作的理解与研究
    当我们在地址栏中输入一个地址之后,首先起作用的是UI线程(UI thread)。我们输入的地址千奇百怪,但正常的来说绝大部分确实也是URL,但这个是需要UI thread进行判断的。

    解析URL

    首先他会分析这个URI是什么,如果是http相关会进行DNS查询等,然后直接调用http相关的模块。但也有可能是一个搜索地址。

    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(&params);
    
        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;
    }
    

    综合上边的理解,实际上的流程如下:
    浏览器进程之间协作的理解与研究

    下一篇文章我们就详细的来说说,浏览器从发出请求到收到请求以及处理的流程~


    起源地下载网 » 浏览器进程之间协作的理解与研究

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元