多執行緒指令碼檢查啟動**:
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...