• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2021-05-08 13:39 Aet 隐藏边栏 |   抢沙发  20 
文章评分 3 次,平均分 5.0

进程

主进程

  1. Browser进程
  2. 与用户交互的界面

渲染进程

  1. Renderer进程
  2. 解析html,css,执行javascript脚本

GPU进程

  1. 负责网页和主界面的绘制

Utility进程

  1. 各种服务,如网络服务,音频服务

V8代理解析工具进程

  1. 跑PAC代理脚本时的进程

Crashpad-handler进程

  1. 奔溃处理进程

Ppapi进程

  1. ppapi插件的进程

进程模式

  1. 浏览器提供了4种进程模式,如下。

single process

  1. 只有browser进程,没有renderer进程
  2. 所有工作都在browser进程里运行

process-per-tab

  1. 一个tab对应一个renderer进程

process-per-site

  1. 每个域名使用一个renderer进程

process-per-site-instance

  1. 每个域名实例使用一个renderer进程

线程

Browser进程中的线程

  1. 主线程
    1. 浏览器进程中的
      1. BrowserThread::UI
      2. 负责更新用户界面,响应用户操作
    2. 渲染器进程中的
      1. 运行大多数Blink
  2. IO线程
    1. 浏览器进程中的
      1. BrowserThread::IO
      2. 负责处理IPC和网络请求
    2. 渲染器进程中的
      1. 处理IPC
  3. 线程池里的若干线程
  4. 一些特殊目的的线程

所谓物理线程

  1. Thread
  2. 操作系统提供的线程,可以使用base::Thread创建,但是没必要创建
  3. 两个task先后Post到同一个Thread上,那么这两个task一定会在同一个物理线程上,以post的顺序先后执行

所谓虚拟线程

  1. Sequence
  2. 由Chrome维护的虚拟线程
  3. 两个task先后Post到同一个Sequence上,那么这两个task可能会在同一条物理线程上执行,也可能在不同的物理线程执行,但是执行顺序一定跟post顺序一致的
  4. 如果不是跟UI相关,尽量使用Sequence,比如去后台Load一个大文件

SEQUENCE_CHECKER/DCHECK_CALLED_ON_VALID_SEQUENCE使用来检查函数有没有在指定的Squence中运行的。
如果需要检查有没有在指定的线程运行,可以用THREAD_CHECKER/DCHECK_CALLED_ON_VALID_THREAD

可调用对象

介绍

  1. BindRepeating返回RepeatingCallback函数对象
  2. BindOnce返回OnceCallback函数对象
  3. 区别是RepeatingCallback以调用多次,而OnceCallback则只能调用一次

别名

Task

  1. 一个task是一个被放到一个异步执行的队列中的base::OnceClosure
  2. base::OnceClosure存储了函数指针和参数,它有一个方法Run(),Run可以通过绑定的参数启动这个函数指针,可以使用base::BindOnce来创建一个base::OnceClosure
  3. 跟std::bind比起来,Chromium的base::Bind语法上更加简洁
  4. 提供了参数生命周期的管理

stl

chrome

运行方式

对于一组task来说:

并行任务

  1. 对于可以同时运行在任何线程上,且不用在意执行的顺序的任务或不会与其他任务有互斥需求的任务。

有序任务

  1. 任务按发布的顺序执行,在任何线程上一次执行

单线程

  1. 任务按发布的顺序执行,在单一线程上一次执行
  2. 多个任务如果需要运行在相同的线程上,需要发布到base::SingleThreadTaskRunner

任务优先级和其他参数

生命周期

GetWeakPtr()

  1. 持有该类对象的一个弱引用
  2. Run内部会检查weak_ptr_factory_的有效性
    1. 如果已经失效,会放弃调用并之间返回
  3. 相比之下更安全,但需要额外的空间保存这个weak_ptrfactory
  4. WeakPtr不能跨线程,因此不能将上述实例中的task post到别的线程中去调用。如果执意将上述task post到了别的线程中调用了,表面上是触发了DCHECK,实际上是在没有加锁的情况下,在两个线程中访问这个weak_ptrfactory

base::Owned()

  1. 让对应的Callback函数对象持有参数
  2. 当callback被Reset或者析构时,会同时delete掉持有的对象

base::RetainedRef()

  1. RetainedRef是给智能指针scoped_refptr对象增加引用计数
  2. base::RetainedRef(p)会增加p的引用计数,以确保函数对象在销毁前,p指向的对象不会被析构

  1. 如果传scoped_prefptr<MyFoo>不使用RetainedRef(如下)怎么样?
    1. 编译器会将scoped_refptr隐式转换成MyFoo*指针,然后编译失败。

base::Unretained(this)

  1. 如果要使用的类支持scoped_refptr,那么可以使用base::RetainedRef(this)
  2. 如果要使用的类支持WeakPtr,那么可以使用this->GetAsWeakPtr();
  3. 如果两者都不支持,就只能用Unretained了,Unretained是既不持有,也不增加引用计数,相当于传裸指针。

base::Passed()

  1. Passed主要是为base::BindRepeating设计的
  2. 当使用BindRepeating的时候如果需要传入unique_ptr参数的时候需要使用Passed
  3. 而对于BindOnce在传入unique_ptr的时候,只需要使用std::move()即可

std::move()

  1. std::move使用转移语义传递参数,以避免对象拷贝。

PostTask

Task Post到UI线程中

Task Post到线程池中的某个线程

Task1 Post到别的线程中,再回到原来的线程执行Task2

Task1 Post到别的线程中,再回到原来的线程执行Task2(把task1的结果作为参数传给task2)

创建或从线程池中取一条真实线程,往这个线程Post Task

  1. 往线程池中同一个线程中post task

创建一个虚拟线程,往这个线程中Post Task

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2021-11-20
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享