![](/img/trans.png)
[英]C++ Behavior of priority_queue pop() and top() when queue is empty
[英]C++ priority_queue pop() and top() discrepancy
我很難理解為什么priority_queue pop()調用沒有刪除top()元素。 優先級隊列具有自定義比較結構,因此,較低的數字具有較高的優先級(因此應使用top()進行檢索)。
調試文本(如下)顯示,即使在pop()之后,top()元素也保持不變。
即使我們假設比較結構有某種錯誤,top()應該在pop()之后更改,對嗎? 我還能看些什么以了解為什么會這樣。 目前,priority_queue代碼本身對我來說有點難以理解。
請注意,此行為不一致。 在其他情況下,top()在pop()之后更改。
有任何想法嗎? 謝謝!
調試文本(在push()之前顯示的top()中進行了編輯:
size BEFORE push(): 1 TOP: [1488994840.745965281:0106996627] APPENDING: [1488994840.746157190:0106996627]
size AFTER push(): 2 TOP: [1488994840.745965281:0106996627]
size BEFORE pop(): 2 TOP: [1488994840.745965281:0106996627]
size AFTER pop(): 1 TOP: [1488994840.745965281:0106996627] // <- same top()!!
我將()推送到priority_queue的位置:
void Replica::appendPrepareOK(const PrepareOK &prepareOK) {
PendingPrepare tmpPrepareOK = prepareOK;
lock_guard<mutex> lck (this->lockPendingPrepare);
this->logprint(3, "size BEFORE push(): " + to_string(this->pendingPrepare.size()) + " APPENDING: " + to_string(tmpPrepareOK));
this->pendingPrepare.push(tmpPrepareOK);
this->logprint(3, "size AFTER push(): " + to_string(this->pendingPrepare.size()) + " TOP: " + to_string(this->pendingPrepare.top()));
}
我在priority_queue中彈出()的地方:
void Replica::sendPendingCmds() {
ClockCommand *prepareCmd = NULL;
PrepareOK *prepareOKCmd = NULL;
Broadcast *broadcastCmd = NULL;
{
lock_guard<mutex> lck(this->lockPendingPrepare);
if (! this->pendingPrepare.empty()) {
this->logprint(3, "size BEFORE pop(): " + to_string(this->pendingPrepare.size()) + " TOP: " + to_string(this->pendingPrepare.top()));
PendingPrepare firstCommand = this->pendingPrepare.top();
this->pendingPrepare.pop();
if (! this->pendingPrepare.empty()) {
this->logprint(3, "size AFTER pop(): " + to_string(this->pendingPrepare.size()) + " TOP: " + to_string(this->pendingPrepare.top()));
}
else {
this->logprint(3, "size AFTER pop(): " + to_string(this->pendingPrepare.size()));
}
priority_queue的定義:
typedef priority_queue<PendingPrepare, deque<PendingPrepare>, PendCompare> pendQueue;
自定義PendCompare比較類:
class PendCompare {
public:
bool operator() (const PendingPrepare &a, const PendingPrepare &b) const {
if (a.prepareOK != NULL) {
if (b.prepareOK != NULL) { return a.prepareOK->tsOK > b.prepareOK->tsOK; }
else if (b.prepare != NULL) { return a.prepareOK->tsOK > b.prepare->ts; }
}
else if (a.prepare != NULL) {
if (b.prepareOK != NULL) { return a.prepare->ts > b.prepareOK->tsOK; }
else if (b.prepare != NULL) { return a.prepare->ts > b.prepare->ts; }
}
return false;
}
};
PendingPrepare結構的相關部分:
struct PendingPrepare {
ClockCommand* prepare = NULL;
PrepareOK* prepareOK = NULL;
void operator=(const PrepareOK &b) {
this->prepareOK = new PrepareOK(b);
}
};
感謝大家的協助。 實際查看PendingPrepare內容可以解決此問題。 我做出了可怕的假設,即一次只有一個指針被實例化,而有時會同時實例化兩個指針,這使PendCompare比較類感到困惑。
更好的復制構造函數刪除了另一個指針並使其為NULL,以避免多個實例化,從而解決了該問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.