一次無鎖迴圈佇列的編寫回顧

2021-08-03 00:24:41 字數 2789 閱讀 9700

今天寫了乙個無鎖佇列,**比較短,但是除錯時間比較久,主要的幾個問題是:

函式用法不清楚(cas)

函式起名不準確,導致用錯

演算法不熟練,導致除錯時發現演算法的偏移又問題

**如下:

#ifndef lyy_lib_lock_free_queue_h

#define lyy_lib_lock_free_queue_h

#include

#include

using

std::vector;

namespace lyy ;

struct node ;

class queue

queue(int max_queue_size) : _max_queue_size(max_queue_size)

virtual

void * get() = 0;

virtual

void put(void* t) = 0;

protected:

int _max_queue_size;

};class lockfreequeue : public queue

lockfreequeue(int max_queue_size) : queue(max_queue_size), _head_tail(0)

void * get();

void put(void* t);

int empty();

int full();

private:

bool add_tail(uint64_t &);

bool add_head(uint64_t &);

private:

vector

_data;

uint64_t _head_tail;

};}#endif

cpp:
#include "queue.h"

#include

#include

namespace lyy else

if (cur_size == _max_queue_size - 1)

tail = (tail + 1) % (_max_queue_size);

new_head_tail = (((uint64_t)head)<<32) | tail;

return

true;

}bool lockfreequeue::add_head(uint64_t & new_head_tail) else

if (cur_size == 0)

head = (head + 1) % _max_queue_size;

new_head_tail = (((uint64_t)head)<<32) | tail;

return

true;

}void *lockfreequeue::get() else else

}} while (!suc);

retry = 3;

} while (!cas(&_head_tail, old_head_tail, new_head_tail));

uint32_t head = ((new_head_tail >> 32) + _max_queue_size - 1) % _max_queue_size;

node * node = &_data[head];

do while (!cas(&node->status, status_ready,status_removing));

void *ptr= node->ptr;

node->ptr = null;

node->status = status_idle;

return ptr;

}void lockfreequeue::put(void *ptr) else else

}} while (!suc);

retry = 3;

} while (!cas(&_head_tail, old_head_tail, new_head_tail));

uint32_t tail = new_head_tail & 0xffffffff;

node * node = &_data[(tail + _max_queue_size - 1) % _max_queue_size];

do while (!cas(&node->status, status_idle, status_adding));

node->ptr = ptr;

node->status = status_ready;

}}

測試**:

#include "queue.h"

#include

#include

#include

#include

struct context ;

struct data

};void* put(void *ptr)

}void *get(void *ptr)

}}int main()

for (int i = 0; i < get_thread_num; ++i)

}

add_tail&add_head 的名字問題:add_head和add_tail名字表達不準確,add_head應該叫remove_head

cas的比較結果沒有注意函式結果,導致出錯

一次git事故的回顧和學習

此次回顧是針對之前在上海開發過程中,呂鵬提交的 被我覆蓋掉的事故。希望通過學習了解事故發生的原因,避免以後在工作中重蹈覆轍。以下是我自己的理解,可能會有錯誤,大家及時指正。a 事件回顧 為了簡便描述,s代表我,l代表呂鵬。i.l進行了數次提交。ii.s使用pull merge進行拉取,出現了合併衝突...

spring 迴圈依賴的一次 理解

在看spring 迴圈依賴的問題中,知道原理,網上一堆的資料有講原理。但今天在看 過程中,又產生了疑問。疑問點如下 疑問點 先進行 dependon 判斷 string dependson mbd.getdependson if dependson null registerdependentbea...

js方法佇列的一次實踐

場景 專案中有乙個需求,發布故事線,發布會呼叫乙個介面,改介面返回進度條的必要資訊,進度資訊由mqtt推送過來,在正常網路情況下,介面返回速度應該比mqtt推送先一步完成,但是在網路慢的情況下,介面就遲於mqtt推送的速度。mqtt會推送多條訊息過來,執行多次 這樣會造成進度條卡死的現象。解決辦法 ...