-
物理线程(Thread)
:操作系统提供的线程,可以使用base::Thread创建,但是没必要创建,chromium提供UI线程,IO线程,线程池等。 -
虚拟线程(Sequence)
:由于Chrome维护的虚拟线程。
区别:
-
两个task先后Post到同一个Thread上,那么这两个task一定会在同一个物理线程上,以post的顺序先后执行。
-
两个task先后Post到同一个Sequence上,那么这两个task可能会在同一条物理线程上执行,也可能在不同的物理线程执行,但是执行顺序一定跟post顺序一致的。
如果不是跟UI相关,尽量使用Sequence,比如去后台Load一个大文件
class MyView {
public:
MyView() {
//创建Squence
task_runner_ = ...;
//将sequence_checker_与当前Sequence脱离绑定
DETACH_FROM_SEQUENCE(sequence_checker_);
}
void Load() {
//Post到task_runner_ Squence中执行
task_runner_->PostTask(FROM_HERE,
base::BindOnce(&MyView::LoadImpl, base::Unretained(this)));
}
private:
void LoadImpl() {
//检查是不是在task_runner_ Squence调用
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
//加载
Data data = ...;
//Post到UI线程
base::PostTask(FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&MyView::LoadComplete, base::Unretained(this), std::move(data)));
}
void LoadComplete(Data data) {
//检查是不是在UI线程中调用
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}
private:
scoped_refptr<SequencedTaskRunner> task_runner_;
SEQUENCE_CHECKER(sequence_checker_);
};
SEQUENCE_CHECKER
/DCHECK_CALLED_ON_VALID_SEQUENCE
使用来检查函数有没有在指定的Squence中运行的。
如果需要检查有没有在指定的线程运行,可以用THREAD_CHECKER
/DCHECK_CALLED_ON_VALID_THREAD
THREAD_CHECKER(thread_checker_);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);