深刻V8引擎-初始化默認Platform

  原本尋思着寫一篇"'Hello' + ', World'"是怎麼從JS代碼編譯而後輸出的,然而compile過程的複雜性遠超個人想象,強上怕會走火入魔,仍是老老實實先回家種田,找點鹹魚方法先寫着。雖說是鹹魚方法,可是V8任何一塊拿出來都不簡單,以前講的Time模塊說實話大概是屬於源碼裏面幼兒園級別的,此次試試難一點的。git

  V8的源碼在本地編譯完成後,會提供一個hello-world.cc的sample,裏面有新手用戶標準的初始化流程,以下。github

int main(int argc, char* argv[]) { // Initialize V8. // 這個方法在mac不做爲
  v8::V8::InitializeICUDefaultLocation(argv[0]); // 讀取指定名稱的配置文件 也不用鳥
  v8::V8::InitializeExternalStartupData(argv[0]); // 生成一個默認的platform對象
  std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform(); // 初始化剛纔的platform
  v8::V8::InitializePlatform(platform.get()); // V8的初始化
 v8::V8::Initialize(); // ...
}

  前兩步不用去管,在入門階段用不上。編程

  第三步是主要內容,探究生成的默認platform對象(固然也能夠選擇本身定製一個platform對象),這個類主要負責管理線程池、調用棧、事件隊列等一些雜活。多線程

  這一篇不會去深刻方法一步一步走,裏面內容太過於雜亂,跳來跳去的,先總體介紹一下全部涉及的類,有一個初步的印象(建議深刻閱讀全部基類的英文註釋,解釋的很明白)。異步

 

Platformide

  首先固然是核心類Platform,但這是一個基類,裏面的大部分方法都是虛函數。函數

/** * V8 Platform abstraction layer. * * The embedder has to provide an implementation of this interface before * initializing the rest of V8. */
class Platform {};

  若是須要定製platform來初始化V8,須要繼承這個類並實現那些方法。通常狀況下固然能夠V8默認提供的類,即DefaultPlatform。工具

class DefaultPlatform : public Platform { public: // 接受一個枚舉值、一個TracingController類的構造函數
    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: // 最大線程池數量 默認爲8
    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_; // 計數方法 用的是以前介紹的Time模塊
 TimeFunction time_function_for_testing_; }; /** * V8 Tracing controller. * * Can be implemented by an embedder to record trace events from V8. */
class TracingController {}; /** * A V8 memory page allocator. * * Can be implemented by an embedder to manage large host OS allocations. */
class PageAllocator {};

  只選了一些初始化相關的方法,其實內容遠比這個要多。其中還定義了兩個相似於Platform的基類變量,一個負責調用棧追蹤,一個負責內存管理。oop

 

TaskRunner/Threadpost

  接下來是任務執行者、線程,由於這二者基本上成對出現,因此放一塊兒來看。

// Thread //
// Thread objects are used for creating and running threads. When the start() // method is called the new thread starts running the run() method in the new // thread. The Thread object should not be deallocated before the thread has // terminated.

class V8_BASE_EXPORT Thread { public: // Start new thread by calling the Run() method on the new thread.
    void Start(); // ...
};

  這是最基礎的Thread,其中定義並實現了Start等常規方法,也有一些虛函數須要繼承去從新實現,除此以外還有一些靜態方法。默認狀況下,V8實現了一個類繼承於Thread,位置十分的隱蔽,在默認TaskRunner的private裏面。

/** * A TaskRunner allows scheduling of tasks. The TaskRunner may still be used to * post tasks after the isolate gets destructed, but these tasks may not get * executed anymore. All tasks posted to a given TaskRunner will be invoked in * sequence. Tasks can be posted from any thread. */
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; // This thread attempts to get tasks in a loop from |runner_| and run them.
      void Run() override; private: DefaultWorkerThreadsTaskRunner* runner_; }; // 獲取下一個task
    std::unique_ptr<Task> GetNext(); bool terminated_ = false; // task隊列
 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兩個類綁起來了。

 

Task

  這個只是一個簡單基類,用來繼承實現任務的。

/** * A Task represents a unit of work. */
class Task { public: virtual ~Task() = default; // 全部的task須要繼承這個類並實現Run方法
  virtual void Run() = 0; };

  因爲HelloWorld的sample並無用到多線程,因此不存在Task類的實現,這裏只能先關注概念。使用時,大概方法以下,寫個僞代碼演示下。

class userTask : public Task { public: void Run() { // do something...
 }; }; void handleTask() { // 新建一個task
  auto task = new userTask(); // 加入隊列
 queue_.push_back(task); // 喚醒線程
 thread_.signal(); // 線程處理task
  while(true) { if(queue_.empty()) break; auto task = queue_pop_back(); task->Run(); } // 線程等待喚醒
 thread_.wait(); }

  過程跟其實libuv的異步操做差很少,感受編程的套路也就那樣,看多了源碼或者有實際開發經驗的都熟悉。

  

  這一篇就先介紹一些類(調用棧和內存管理先放着),瞭解後基本上V8中關於Platform的內容就差很少了。關於Thread、TaskRunner、Task三者的聯繫與運做,由於C++是速成的,沒去了解這些東西的實際運用,因此暫時不在這裏班門弄斧了。以前學Java的時候瞭解過線程,感受不管是API的名字仍是概念都差很少,有興趣的能夠本身去看看。

相關文章
相關標籤/搜索