位元幣原始碼分析 多執行緒檢查指令碼

2021-09-11 10:10:03 字數 3552 閱讀 9057

多執行緒指令碼檢查啟動**:

bool

(config &config, boost::thread_group &threadgroup, cscheduler &scheduler)

}...

}static ccheckqueuescriptcheckqueue(128);

void

threadscriptcheck

()複製**

任務佇列**:

template

class

ccheckqueue

void

thread

()

bool

wait

()

void

add(std::vector

&vchecks)

ntodo += vchecks.size();

if (vchecks.size() == 1) else

if (vchecks.size() > 1)

}bool

isidle

() ~ccheckqueue() {}

}bool ccheckqueue::loop(bool fmaster = false) else

while (queue.empty())

nidle++;

cond.wait(lock);

nidle--;

}nnow = std::max(

1u, std::min(nbatchsize, (unsigned

int)queue.size() /

(ntotal + nidle + 1)));

vchecks.resize(nnow);

for (unsigned

int i = 0; i < nnow; i++)

fok = fallok;

}// execute work; 執行本執行緒剛分到的工作。

for (t &check : vchecks)

vchecks.clear();

} while (true);

}複製**

使用解讀:

佇列中使用了模板類,執行的驗證任務由t標識,t都必須提供乙個過載的operator()方法,並且反回乙個bool。 預設為主執行緒push 批量任務到佇列中,其他的工作執行緒去處理這些任務,當主線程push完任務後,也去處理這些任務,直到任務佇列全部處理完畢。 上述是佇列的實現:主要的任務處理是在loop()函式中; 該佇列會進行兩種呼叫,來處理佇列中的任務:

新增任務後:自動喚醒阻塞的工作執行緒去處理新增的任務;細節請看:void add(std::vector&vchecks)主線程新增完任務後,呼叫bool wait(),也去處理佇列中的任務,佇列中的全部任務處理完後,主線程退出。void add():給類的內部佇列批量新增任務,本次操作受鎖保護,並更新所有的狀態。

如果剛新增的任務數量為1,只喚醒乙個工作執行緒去處理;否則,喚醒全部工作執行緒。

raii機制(resource acquisition is initialization)是bjarne stroustrup首先提出的。要解決的是這樣乙個問題:

在c++中,如果在這個程式段結束時需要完成一些資源釋放工作,那麼正常情況下自然是沒有什麼問題,但是當乙個異常丟擲時,釋放資源的語句就不會被執行。 於是 [bjarne stroustrup] 就想到確保能執行資源釋放**的地方就是在這個程式段(棧幀)中放置的物件的析構函式了,因為 stack winding 會保證它們的析構函式都會被執行。

將初始化和資源釋放都移動到乙個包裝類中的好處:

template

class

ccheckqueuecontrol

}bool

wait

() void

add(std::vector

&vchecks)

~ccheckqueuecontrol()

};複製**

該類主要是用來管理ccheckqueue物件;採用raii機制,保證每次析構該類的物件時,ccheckqueue中的任務佇列被全部處理。 用來構建該物件的任務佇列只能是nil, 或者佇列中無任務。 因為建立的該物件在析構時會呼叫任務佇列的wait()方法去處理完佇列中所有的任務,然後退出。 方法解釋:

在塊來的時候啟用主鏈使用使用了檢查佇列:

static

bool

connectblock

(const config &config, const cblock &block, cvalidationstate &state, cblockindex *pindex,

ccoinsviewcache &view, const cchainparams &chainparams, bool fjustcheck = false)

control.add(vchecks);

}...

}...

}複製**

connectblock將該區塊鏈結到當前啟用鏈上,並更新utxo集合。 在該方法中:使用了全域性物件scriptcheckqueue去構造了乙個臨時的管理物件,並通過該管理物件來操作全域性任務佇列,用來新增任務,以及執行任務。當該臨時的管理物件析構時,會呼叫wait()方法,加入任務處理,處理完所有任務後,該物件析構完成。

cscriptcheck源**:

class

cscriptcheck

cscriptcheck(const cscript &scriptpubkeyin, const amount amountin,

const ctransaction &txtoin, unsigned

int ninin,

uint32_t nflagsin, bool cachein,

const precomputedtransactiondata &txdatain)

: scriptpubkey(scriptpubkeyin), amount(amountin), ptxto(&txtoin),

nin(ninin), nflags(nflagsin), cachestore(cachein),

error(script_err_unknown_error), txdata(txdatain) {}

bool

operator

()()

;

void

swap

(cscriptcheck &check)

scripterror getscripterror

()const

};複製**

**解釋:

詳情見下篇文章:《指令碼驗證》

位元幣原始碼研讀二(交易指令碼)

今天接著寫五個全域性靜態常量,用於定義交易執行序列的規則.1 static const uint32 t sequence final oxffffffff 如果交易中的所有輸入都將nsequence賦值為該全域性變數值,nlocktime將無效 無需考慮交易的鎖定時間,最近的交易達到區塊後,交易立...

位元幣原始碼解讀一

上次在ubuntu系統中將位元處原始碼編譯環境設定好了後,還沒有具體分析裡面的 今天我們就解讀一下。原始碼版本是bitcoin 0.9.5rc2。我們說驗證位元幣客戶端安裝成功就是從 which bitcoind 這個命令進行驗證的,因為位元幣客戶端有兩個。乙個是圖形介面的版本,通常被稱為 bitc...

位元幣原始碼編譯過程

編譯位元幣原始碼 系統環境 ubuntu 16.04 lts 2g記憶體的虛擬機器 1 更新系統的安裝庫,否則很多依賴庫無法從伺服器獲取 apt get update 2 先安裝一些必要的依賴庫 sudo apt get install build essential libtool autotoo...