多執行緒無鎖佇列的實現
阿新 • • 發佈:2019-01-06
一、什麼是多執行緒無鎖佇列?
多執行緒無鎖佇列還是有鎖的,只不過是用了cpu層面的CAS原子操作,用到這個操作,只需要在取佇列元素和新增佇列元素的時候利用CAS原子操作,就可以保證多個執行緒對佇列元素的有序存取;
二、什麼是CAS操作?
CAS = Compare & Set,或是 Compare & Swap;
在windows和Linux平臺均有系統api函式,同時在c++11中也有實現;
//下面這個函式操作在CPU層面是原子操作,這是實現無鎖佇列的基礎;
//這個函式的意思是:只有當dest的只和accum的值相等的時候,才將newval賦值給accum;
//到現在你還是無法理解,為什麼這個操作就可以實現多執行緒對佇列元素的有序操作了呢?
bool
compare_and_swap (
int
*accum,
int
*dest,
int
newval)
{
if
( *accum == *dest ) {
*dest
= newval;
return
true
;
}
return
false
;
}
下面我們用一個demo程式,比較一下使用CAS和不使用CAS存取一個棧的操作;
因為demo程式中使用的是c++11的CAS操作,因此我們先了解一下CAS在C++11中的表現形式;
void test_c11CAS(){
std::atomic<int>head = 1;
inta = 10;
intb = 2;
head.compare_exchange_weak(a,b);
cout
<< "head=" << head << '\n'
<< "a=" << a << '\n'
<< "b=" << b << endl;
}
我們瞭解了c++11的CAS原子操作,我們來看下它到底是怎麼才佇列的操作中發揮作用的 無鎖佇列的效率 ABA的解決方法: 1.把CAS中比較的地址做標記,擴大比較現場,有一個方法就是對指向節點的指標加標記tag,這個方法叫做CAS2,目前不是所有平臺CPU都支援,只有新的x86平臺支援; 2.使用陣列或者佇列,預先分配好空間,在實際的取佇列元素和入佇列元素的時候不涉及地址空間的申請,因此避免了ABA的問題。 多執行緒無鎖佇列在開發中的使用,