環形無鎖佇列

2021-08-19 21:09:45 字數 2905 閱讀 7719

1、元素是先進先出的

由佇列的性質保證的,在環形佇列中通過對佇列的順序訪問保證

2、空間可以重複利用

因為一般的環形佇列都是乙個元素數固定的乙個閉環,可以在環形佇列初始化的時候分配好確定的記憶體空間,當進隊或出隊時只需要返回指定元素記憶體空間的位址即可,這些記憶體空間可以重複利用,避免頻繁記憶體分配和釋放的開銷

3、訊息處理單執行緒化

最典型的生產者消費者模型中,如果引入環形佇列,那麼生成者只需要生成「東西」然後放到環形佇列中即可,而消費者只需要從環形佇列裡取「東西」並且消費即可,沒有任何鎖或者等待,巧妙的高效實現了多執行緒資料通訊。

這樣處理沒有了mutex,但效率較高。值得注意的是,當write和read相等時,表示滿也表示隊滿也表示隊空,這個佇列是2個執行緒共享的,因此在這裡是保證隊空和隊滿時的執行緒安全,那麼整個佇列就是安全的,因為其他情況下read和write根本沒有交集,當他們都在讀寫同乙個index的時候,read執行緒先取走,再把標識置為false,write執行緒是先把內容寫入完後再置true,這個讀寫和置false true的順序一定不能亂否則就會標記位準備好了 。

#include 

#include

#include

#include

#include

#include

using queuepair = std::pair

int, unsigned

char*>;

using cmdqueue = std::pair

bool, queuepair>;

class nonlockqueue

~nonlockqueue()

queuepair *front()

void pop()

bool push(const

void *msg, const

unsigned

int len)

else

return

true;

}return

false;

}private:

bool dump()

// 優先將緩衝中的資料寫入到佇列

cmdqueue[write].second = cachequeue.front();

cmdqueue[write].first = true;

write = ++write % 1024;

cachequeue.pop();

}return

false;

}cmdqueue cmdqueue[1024];

std::queue

cachequeue;

unsigned

int read;

unsigned

int write;

unsigned

char *msg;

unsigned

int msglen;

};static

void *funwrite(void *arg)

return null;

}static

void* funread(void *arg)

std::cout

<< ppair->first << "----"

<< ppair->second << std::endl;

pque->pop();

}return null;

}int main()

pthread_join(t1, null);

pthread_join(t2, null);

return

0;

}

部分結果如下:

不用標識的實現方法,這裡空出乙個單元來標識隊滿,這樣的原則:佇列中有元素則可讀,佇列滿則寫快取

(write - read + max_size) % max_size >= 1

//佇列中有元素

(write + 1) % max_size == read

//佇列滿

另外一種方法

#include 

#include

#include

#include

#include

#include

using queuepair = std::pair

int, unsigned

char*>;

const

unsigned

int max_size = 1024;

class nonlockqueue

~nonlockqueue()

queuepair *front()

void pop()

bool push(const

void *msg, const

unsigned

int len)

else

return

true;

}return

false;

}private:

bool dump()

return

false;

}queuepair cmdqueue[max_size];

std::queue

cachequeue;

unsigned

int read;

unsigned

int write;

};

無鎖環形佇列

環形一讀一寫佇列中,不需要擔心unsigned long溢位問題,因為溢位後自動回歸,相減值還會保留。示例一 注 max count 必須為 2 的指數,即 2,4,8,16.佇列尺寸 define max count 4096 define max mask 4095 max count 1 變數...

dpdk無鎖環形佇列的使用

入口使用dpdk,資料報解包分析後續處理執行緒效能太低,cpu很大一部分浪費在多執行緒鎖開銷上,於是想用dpdk無鎖佇列,看是否有改善。使用前不知道dpdk的ring是否能在收發包之外使用,也沒找到實際使用跟收發包無關的例子 也不需要使用mbuf,需要儲存乙個指標的佇列,直接拿過來用看看可不可以。前...

mySQL無鎖佇列 go 無鎖佇列

無鎖佇列適用場景 兩個執行緒之間的互動資料,乙個執行緒生產資料,另外乙個執行緒消費資料,效率高 缺點 需要使用固定分配的空間,不能動態增加 減少長度,存在空間浪費和無法擴充套件空間問題 package main import fmt reflect strings time type loopque...