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...