本来寻思着写一篇"'Hello' + ', World'"是怎么从JS代码编译然后输出的,然而compile过程的复杂性远超我的想象,强上怕会走火入魔,还是老老实实先回家种田,找点咸鱼方法先写着。虽然说是咸鱼方法,但是V8任何一块拿出来都不简单,之前讲的Time模块说实话大概是属于源码里面幼儿园级别的,这次试试难一点的。

  V8的源码在本地编译完成后,会提供一个hello-world.cc的sample,里面有新手用户标准的初始化流程,如下。

  1. int main(int argc, char* argv[]) {
  2. // Initialize V8.
  3. // 这个方法在mac不作为
  4. v8::V8::InitializeICUDefaultLocation(argv[]);
  5. // 读取指定名称的配置文件 也不用鸟
  6. v8::V8::InitializeExternalStartupData(argv[]);
  7. // 生成一个默认的platform对象
  8. std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
  9. // 初始化刚才的platform
  10. v8::V8::InitializePlatform(platform.get());
  11. // V8的初始化
  12. v8::V8::Initialize();
  13.  
  14. // ...
  15. }

  前两步不用去管,在入门阶段用不上。

  第三步是主要内容,探究生成的默认platform对象(当然也可以选择自己定制一个platform对象),这个类主要负责管理线程池、调用栈、事件队列等一些杂活。

  这一篇不会去深入方法一步一步走,里面内容太过于杂乱,跳来跳去的,先整体介绍一下所有涉及的类,有一个初步的印象(建议深入阅读所有基类的英文注释,解释的很明白)。

Platform

  首先当然是核心类Platform,但这是一个基类,里面的大部分方法都是虚函数。

  1. /**
  2. * V8 Platform abstraction layer.
  3. *
  4. * The embedder has to provide an implementation of this interface before
  5. * initializing the rest of V8.
  6. */
  7. class Platform {};

  如果需要定制platform来初始化V8,需要继承这个类并实现那些方法。一般情况下当然可以V8默认提供的类,即DefaultPlatform。

  1. class DefaultPlatform : public Platform {
  2. public:
  3. // 接受一个枚举值、一个TracingController类的构造函数
  4. explicit DefaultPlatform(
  5. IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
  6. std::unique_ptr<v8::TracingController> tracing_controller = {});
  7. ~DefaultPlatform() override;
  8. // 设置线程池大小
  9. void SetThreadPoolSize(int thread_pool_size);
  10. // 初始化线程池、管理线程任务相关的方法
  11. void EnsureBackgroundTaskRunnerInitialized();
  12. private:
  13. // 最大线程池数量 默认为8
  14. static const int kMaxThreadPoolSize;
  15.  
  16. int thread_pool_size_;
  17. IdleTaskSupport idle_task_support_;
  18. // 线程任务启动器
  19. std::shared_ptr<DefaultWorkerThreadsTaskRunner> worker_threads_task_runner_;
  20. // 工具类
  21. std::unique_ptr<TracingController> tracing_controller_;
  22. std::unique_ptr<PageAllocator> page_allocator_;
  23. // 计数方法 用的是之前介绍的Time模块
  24. TimeFunction time_function_for_testing_;
  25. };
  26.  
  27. /**
  28. * V8 Tracing controller.
  29. *
  30. * Can be implemented by an embedder to record trace events from V8.
  31. */
  32. class TracingController {};
  33.  
  34. /**
  35. * A V8 memory page allocator.
  36. *
  37. * Can be implemented by an embedder to manage large host OS allocations.
  38. */
  39. class PageAllocator {};

  只选了一些初始化相关的方法,其实内容远比这个要多。其中还定义了两个类似于Platform的基类变量,一个负责调用栈追踪,一个负责内存管理。

TaskRunner/Thread

  接下来是任务执行者、线程,因为这两者基本上成对出现,所以放一起来看。

  1. // Thread
  2. //
  3. // Thread objects are used for creating and running threads. When the start()
  4. // method is called the new thread starts running the run() method in the new
  5. // thread. The Thread object should not be deallocated before the thread has
  6. // terminated.
  7.  
  8. class V8_BASE_EXPORT Thread {
  9. public:
  10. // Start new thread by calling the Run() method on the new thread.
  11. void Start();
  12. // ...
  13. };

  这是最基础的Thread,其中定义并实现了Start等常规方法,也有一些虚函数需要继承去重新实现,除此之外还有一些静态方法。默认情况下,V8实现了一个类继承于Thread,位置十分的隐蔽,在默认TaskRunner的private里面。

  1. /**
  2. * A TaskRunner allows scheduling of tasks. The TaskRunner may still be used to
  3. * post tasks after the isolate gets destructed, but these tasks may not get
  4. * executed anymore. All tasks posted to a given TaskRunner will be invoked in
  5. * sequence. Tasks can be posted from any thread.
  6. */
  7. class TaskRunner {};
  8.  
  9. class DefaultWorkerThreadsTaskRunner : public TaskRunner {
  10. public:
  11. using TimeFunction = double (*)();
  12. DefaultWorkerThreadsTaskRunner(uint32_t thread_pool_size, TimeFunction time_function);
  13. private:
  14. class WorkerThread : public Thread {
  15. public:
  16. explicit WorkerThread(DefaultWorkerThreadsTaskRunner* runner);
  17. ~WorkerThread() override;
  18.  
  19. // This thread attempts to get tasks in a loop from |runner_| and run them.
  20. void Run() override;
  21. private:
  22. DefaultWorkerThreadsTaskRunner* runner_;
  23. };
  24. // 获取下一个task
  25. std::unique_ptr<Task> GetNext();
  26.  
  27. bool terminated_ = false;
  28. // task队列
  29. DelayedTaskQueue queue_;
  30. // 线程池
  31. std::vector<std::unique_ptr<WorkerThread>> thread_pool_;
  32. // 计数方法
  33. TimeFunction time_function_;
  34. std::atomic_int single_worker_thread_id_{};
  35. uint32_t thread_pool_size_;
  36. };

  这里顺便把TaskRunner相关的内容也一并放出来,大部分内容可以看命名。内部类的初始化参数类型是外部类,V8完全把Thread、TaskRunner两个类绑起来了。

Task

  这个只是一个简单基类,用来继承实现任务的。

  1. /**
  2. * A Task represents a unit of work.
  3. */
  4. class Task {
  5. public:
  6. virtual ~Task() = default;
  7. // 所有的task需要继承这个类并实现Run方法
  8. virtual void Run() = ;
  9. };

  由于HelloWorld的sample并没有用到多线程,所以不存在Task类的实现,这里只能先关注概念。使用时,大概方法如下,写个伪代码演示下。

  1. class userTask : public Task {
  2. public:
  3. void Run() {
  4. // do something...
  5. };
  6. };
  7.  
  8. void handleTask() {
  9. // 新建一个task
  10. auto task = new userTask();
  11. // 加入队列
  12. queue_.push_back(task);
  13. // 唤醒线程
  14. thread_.signal();
  15. // 线程处理task
  16. while(true) {
  17. if(queue_.empty()) break;
  18. auto task = queue_pop_back();
  19. task->Run();
  20. }
  21. // 线程等待唤醒
  22. thread_.wait();
  23. }

  过程跟其实libuv的异步操作差不多,感觉编程的套路也就那样,看多了源码或者有实际开发经验的都熟悉。

  

  这一篇就先介绍一些类(调用栈和内存管理先放着),了解后基本上V8中关于Platform的内容就差不多了。关于Thread、TaskRunner、Task三者的联系与运作,因为C++是速成的,没去了解这些东西的实际运用,所以暂时不在这里班门弄斧了。之前学Java的时候了解过线程,感觉无论是API的名字还是概念都差不多,有兴趣的可以自己去看看。

深入V8引擎-初始化默认Platform的更多相关文章

  1. 深入V8引擎-初始化之InitPlatform

    上一篇其实想讲初始化的第二步,但是内容比较无聊,所以换了一个话题,谈了谈v8的命名空间和宏,稍微轻松一下. 在这里还是接着说说初始化过程,毕竟写博客的初衷是对自己努力的记录,不是为了吸粉,这篇没图,对 ...

  2. 深入V8引擎-默认Platform之mac篇(2)

    先说结论,V8引擎在默认Platform中初始化的这个线程是用于处理类似于setTimeout的延时任务. 另外附一些图,包括继承树.关键属性归属.纯逻辑工作流程,对代码木得兴趣的看完图可以X掉了. ...

  3. 深入V8引擎-默认Platform之mac篇(1)

    又到了常规的堆砌代码凑文章字数环节,很多API我就直接贴官方的英文释义,个人翻译其实有时候并不是很准确,搞错了甚至会误导,还是尽量自己去理解. 首先看看入口方法. std::unique_ptr< ...

  4. 深入V8引擎-引擎内部类管理解析

    v8的初始化三部曲,前面花了三篇解决了第一步,由于只是生成了一个对象,第二步就是将其嵌入v8中,先看一下三个步骤. // 生成默认Platform对象 std::unique_ptr<v8::P ...

  5. 浅谈V8引擎中的垃圾回收机制

    最近在看<深入浅出nodejs>关于V8垃圾回收机制的章节,转自:http://blog.segmentfault.com/skyinlayer/1190000000440270 这篇文章 ...

  6. google v8引擎常见问题

    最近在项目中使用v8来进行扩展,下面简单说一下使用v8过程中遇到的一些问题.   v8的多线程调用 最初调研v8的测试代码是单线程的,后来一个项目在多线程中使用,出现了一些问题,后来看到参考3中的才恍 ...

  7. 一文搞懂V8引擎的垃圾回收

    引言 作为目前最流行的JavaScript引擎,V8引擎从出现的那一刻起便广泛受到人们的关注,我们知道,JavaScript可以高效地运行在浏览器和Nodejs这两大宿主环境中,也是因为背后有强大的V ...

  8. 探究JS V8引擎下的“数组”底层实现

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/np9Yoo02pEv9n_LCusZn3Q作者:李超 JavaScript 中的数组有很多特性 ...

  9. 浅谈Chrome V8引擎中的垃圾回收机制

    垃圾回收器 JavaScript的垃圾回收器 JavaScript使用垃圾回收机制来自动管理内存.垃圾回收是一把双刃剑,其好处是可以大幅简化程序的内存管理代码,降低程序员的负担,减少因 长时间运转而带 ...

随机推荐

  1. maven 学习---Eclipse构建Maven项目

    1. 安装m2eclipse插件    要用Eclipse构建Maven项目,我们需要先安装meeclipse插件    点击eclipse菜单栏Help->Eclipse Marketplac ...

  2. 【推荐】全球最全面的Telegram组群频道的集合网站 持续收集中

    全球最全面的Telegram组群频道的集合网站 https://www.telegramgroup.org Telegram 组群频道分享 可搜索自己想找的组群频道 从小白到大神,一个 telegra ...

  3. 数据库MySQL学习笔记高级篇

    数据库MySQL学习笔记高级篇 写在前面 学习链接:数据库 MySQL 视频教程全集 1. mysql的架构介绍 mysql简介 概述 高级Mysql 完整的mysql优化需要很深的功底,大公司甚至有 ...

  4. k8s volume存储卷(四)

    介绍 volume存储卷是Pod中能够被多个容器访问的共享目录,kubernetes的volume概念,用途和目的与docker的volume比较类似,但两者不能等价,首先,kubernetes中的v ...

  5. 关于Apache本地能访问外网不能访问的问题

    title: 关于Apache本地能访问外网不能访问的问题 date: 2018-08-05 19:22:12 tags: web --- 在配置apache和tomcat时,把它们都配置好,放到服务 ...

  6. ping脚本--无网不利

    一.本文主要涉及的内容 二.预备知识 1.打印网络接口列表 2.提取IP地址的小套路 3.更改网卡的MAC地址 4.高速的ping工具:fping 三.套路连招 1.通过一个for循环和ping列出所 ...

  7. 算法竞赛入门经典 LA 4329(树状数组)

    题意: 一排有着不同能力值的人比赛,规定裁判的序号只能在两人之间,而且技能值也只能在两人之间 问题: <算法竞赛入门经典-训练指南>的分析: 上代码: #include<iostre ...

  8. 03-numpy-笔记-expand_dims

    >>> x = np.array([[1,2,3],[4,5,6]]) >>> x.shape (2, 3) >>> np.expand_dims ...

  9. 初次运行git时的配置

    初次运行git时的配置 # 参考文档 https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%88%9D%E6%AC%A1%E8%BF%90%E8% ...

  10. python 并行处理数据

    来源:https://blog.csdn.net/weixin_42001089/article/details/88843152 import multiprocessing import time ...