EOS區塊鏈究竟有幾個執行緒 星河公鏈

2022-09-23 03:48:10 字數 3634 閱讀 1851

一 nodeos工作執行緒

nodeso節點的工作執行緒包括:乙個主線程,乙個訊號處理執行緒和兩個執行緒池。

主線程:main函式啟動執行緒,該執行緒執行完程式初始化工作後,會呼叫app().io_service.run(), 啟動boost::asio::io_service的非同步io服務,通過非同步io方式完成節點塊生產,交易處理等主要業務工作。

訊號處理執行緒:子執行緒,通過非同步io服務,接收系統訊號並處理。

執行緒池,執行緒池啟動的工作執行緒數可通過啟動引數配置。

controller執行緒池: 非同步執行塊block_state建立,塊中交易驗證時的交易解簽名計算。

生產者外掛程式執行緒池:負責非同步執行交易解簽名計算。

? 採用預設配置(每個執行緒池2個工作執行緒),nodeos節點匯流排程數是6個,通過pstree命令可檢視:

? nodeos有乙個主線程pid=32385,該主線程有5個子執行緒,32386~32390。

二 主線程

? main函式執行執行緒:main函式最後呼叫app().exec(),啟動io_service服務。

app()是application例項,application中定義了io_service物件io_serv:

class application

application::application():my(new application_impl())

boost::asio::io_service& get_io_service()

//啟動io服務

void application::exec()

void application::quit()

其它外掛程式通過get_io_service()函式,獲取io_serv,進行非同步io投遞。

程式退出時,會呼叫quit()函式,結束io服務。

? nodeos節點交易處理,出塊,塊驗證等主要業務操作都是在該執行緒執行的,因為eos中交易不支援並行處理,所以application中的io_serv是不允許在除主線程之外的其它執行緒中重複執行io_serv.run()操作的。

? 看到application::exec()中的**,有些人可能會有疑問:asio::io_service監聽的io埠都完成(沒有待監聽的io埠)時,io_serv->run()就會退出。這裡io_serv->run()只呼叫了一次,沒有迴圈呼叫,不會退出麼?

? nodeos投遞到application::io_serv的io處理handle函式,會重複投遞該io埠。所以在handle處理函式完成時,io_serv中總會有待完成io存在,io_serv->run()就不會退出,下面以producer_plugin中的_timer為例,看一下這個投遞過程:

producer_plugin::producer_plugin()

: my(new producer_plugin_impl(app().get_io_service()));

class producer_plugin_impl

boost::asio::deadline_timer _timer;

};? producer_plugin()在構造時傳入app().get_io_service()構造了producer_plugin_impl:: _timer; 在節點的生產迴圈函式中可以看到, _timer的handle函式中會呼叫schedule_production_loop()函式,而在該函式中,又會呼叫 _timer.asyncwait()重複投遞 _timer到ioservice中:三 訊號處理執行緒

建立io_service物件sig_io_serv;

將sigint訊號投遞到io_service物件,並繫結訊號處理函式,當系統傳送sigint訊號時,會觸發該處理函式。

建立sig_thread訊號處理執行緒,在該執行緒中呼叫sig_io_serv->run(),等待訊號觸發,呼叫相應處理函式。

訊號處理執行緒只處理sigint,sigterm,sigpipe這三個系統訊號,一旦收到訊號,會呼叫退出操作,使nodeos退出。

四 controller執行緒池

4.1 定義及建立

struct controller_impl

controller_impl( const controller::config& cfg, controller& s ):self(s),

chain_id( cfg.genesis.compute_chain_id() ),

read_mode( cfg.read_mode ),

...thread_pool( cfg.thread_pool_size )

controller執行緒池定義在controller_impl中;

根據配置引數中設定的thread_pool_size建立相應數量的工作執行緒。

4.2 非同步任務

? 執行塊相關操作時,較耗時且與排序無關的動作都會投遞到controller執行緒池執行。eos目前投遞到該執行緒池執行的操作有兩個:

? 1 塊交易驗證時的解簽名操作;

? 2 塊狀態block_state資料建立操作(兩輪共識計算都在這裡完成)。

4.2.1 解簽名操作

? 節點收到塊,會呼叫apply_block()函式執行塊中交易,進行塊驗證。期間會投遞交易解簽名計算到controller執行緒池:

? 解簽名投遞函式create_signing_keys_futrue():

**程池thread_pool中非同步執行解簽名函式,非同步解簽名的執行結果,會放入交易的signing_keys_future中。

真正解簽名演算法是trn.get_signature_keys(),解出的公鑰放到recovered_pub_keys中。

4.2.2 block_state建立

五 生產者執行緒池

5.1 定義及建立

? 生產者執行緒池定義在producer_plugin_impl中,執行外掛程式初始化函式plugin_initialize()時會根據配置引數建立工作執行緒。

class producer_plugin_impl : public std::enable_shared_from_this

void producer_plugin::plugin_initialize(const boost::program_options::variables_map& options)

5.2 非同步任務

? 生產者執行緒池負責的工作任務有兩個:

1. 為接收到的投遞交易進行非同步解簽名計算;

2. 等待解簽名計算完成,將交易投遞到主線程的非同步io服務中處理。

? 這兩個工作任務都在同乙個函式中投遞執行:該函式在節點收到其它節點/客戶端投遞的交易時被呼叫:

投遞非同步解簽名計算任務到 _threadpool執行緒池( 生產者執行緒池),計算結果放到

trx->signing_keys_future中。

投遞非同步任務到 _thread_pool執行緒池,該任務等待將非同步解簽名計算結束的交易投遞到主線程的io_service中執行。

5.3 執行緒池關閉

? 當呼叫外掛程式shutdown函式時,會執行執行緒池關閉動作,前程池中的工作執行緒退出。

六 鏈結

星河公鏈

依託於區塊鏈的TD源鏈究竟有什麼特性

從物聯網 iot 融合到無銀行賬戶的初創企業,都表達了對2019年區塊鏈的期望。自從中本聰satoshi著名的 將區塊鏈引入以來,已經有十多年了。這項技術已經遠遠超出了加密貨幣,影響了許多行業。我們將揭示為什麼無論數字貨幣發生什麼變化,區塊鏈都會記錄下來。區塊鏈的前景被廣泛看好,主要就是基於區塊鏈的...

區塊鏈研究總結 EOS

本文為區塊鏈技術總結及發展展望一文的子章節。業內對於誰是第三代區塊鏈系統代表還沒達成一致,不過eos絕對是個不可忽視的競爭者。eos致力於解決以太坊使用過程的一系列痛點,推動去中心化應用的發展。eos由bm github賬號bytemaster 通過史上最大規模ico專案發起,目標是成為區塊鏈世界的...

區塊鏈 EOS 環境的搭建

目錄概述 開始編譯並安裝 如上圖,目標是主要包含幾個工具 nodeos eos的核心部分,能夠提供各種api服務,能夠同步節點。cleos 是用於給使用者操作的部分,只要nodeos配置好並執行後,都是通過cleos對其進行呼叫的 當然也可以呼叫別的節點的nodeos介面 keosd 用於安全儲存使...