原本寻思着写一篇"'Hello' + ', World'"是怎么从JS代码编译而后输出的,然而compile过程的复杂性远超个人想象,强上怕会走火入魔,仍是老老实实先回家种田,找点咸鱼方法先写着。虽说是咸鱼方法,可是V8任何一块拿出来都不简单,以前讲的Time模块说实话大概是属于源码里面幼儿园级别的,此次试试难一点的。
int main(int argc, char* argv[]) {
v8::V8::InitializeICUDefaultLocation(argv[0]);
v8::V8::InitializeExternalStartupData(argv[0]);
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
}复制代码
第三步是主要内容,探究生成的默认platform对象(固然也能够选择本身定制一个platform对象),这个类主要负责管理线程池、调用栈、事件队列等一些杂活。
这一篇不会去深刻方法一步一步走,里面内容太过于杂乱,跳来跳去的,先总体介绍一下全部涉及的类,有一个初步的印象(建议深刻阅读全部基类的英文注释,解释的很明白)。
首先固然是核心类Platform,但这是一个基类,里面的大部分方法都是虚函数。
class Platform {};复制代码
若是须要定制platform来初始化V8,须要继承这个类并实现那些方法。通常状况下固然能够V8默认提供的类,即DefaultPlatform。
class DefaultPlatform : public Platform {
public:
explicit DefaultPlatform( IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, std::unique_ptr<v8::TracingController> tracing_controller = {});
~DefaultPlatform() override;
void SetThreadPoolSize(int thread_pool_size);
void EnsureBackgroundTaskRunnerInitialized();
private:
static const int kMaxThreadPoolSize;
int thread_pool_size_;
IdleTaskSupport idle_task_support_;
std::shared_ptr<DefaultWorkerThreadsTaskRunner> worker_threads_task_runner_;
std::unique_ptr<TracingController> tracing_controller_;
std::unique_ptr<PageAllocator> page_allocator_;
TimeFunction time_function_for_testing_;
};
class TracingController {};
class PageAllocator {};复制代码
只选了一些初始化相关的方法,其实内容远比这个要多。其中还定义了两个相似于Platform的基类变量,一个负责调用栈追踪,一个负责内存管理。
接下来是任务执行者、线程,由于这二者基本上成对出现,因此放一块儿来看。
class V8_BASE_EXPORT Thread {
public:
void Start();
};复制代码
这是最基础的Thread,其中定义并实现了Start等常规方法,也有一些虚函数须要继承去从新实现,除此以外还有一些静态方法。默认状况下,V8实现了一个类继承于Thread,位置十分的隐蔽,在默认TaskRunner的private里面。
class TaskRunner {};
class DefaultWorkerThreadsTaskRunner : public TaskRunner {
public:
using TimeFunction = double (*)();
DefaultWorkerThreadsTaskRunner(uint32_t thread_pool_size, TimeFunction time_function);
private:
class WorkerThread : public Thread {
public:
explicit WorkerThread(DefaultWorkerThreadsTaskRunner* runner);
~WorkerThread() override;
void Run() override;
private:
DefaultWorkerThreadsTaskRunner* runner_;
};
std::unique_ptr<Task> GetNext();
bool terminated_ = false;
DelayedTaskQueue queue_;
std::vector<std::unique_ptr<WorkerThread>> thread_pool_;
TimeFunction time_function_;
std::atomic_int single_worker_thread_id_{0};
uint32_t thread_pool_size_;
};复制代码
这里顺便把TaskRunner相关的内容也一并放出来,大部份内容能够看命名。内部类的初始化参数类型是外部类,V8彻底把Thread、TaskRunner两个类绑起来了。
class Task {
public:
virtual ~Task() = default;
virtual void Run() = 0;
};复制代码
因为HelloWorld的sample并无用到多线程,因此不存在Task类的实现,这里只能先关注概念。使用时,大概方法以下,写个伪代码演示下。
class userTask : public Task {
public:
void Run() {
};
};
void handleTask() {
auto task = new userTask();
queue_.push_back(task);
thread_.signal();
while(true) {
if(queue_.empty()) break;
auto task = queue_pop_back();
task->Run();
}
thread_.wait();
}复制代码
过程跟其实libuv的异步操做差很少,感受编程的套路也就那样,看多了源码或者有实际开发经验的都熟悉。
这一篇就先介绍一些类(调用栈和内存管理先放着),了解后基本上V8中关于Platform的内容就差很少了。关于Thread、TaskRunner、Task三者的联系与运做,由于C++是速成的,没去了解这些东西的实际运用,因此暂时不在这里班门弄斧了。以前学Java的时候了解过线程,感受不管是API的名字仍是概念都差很少,有兴趣的能够本身去看看。