1. 程式人生 > >多執行緒無鎖佇列的實現

多執行緒無鎖佇列的實現

一、什麼是多執行緒無鎖佇列?

多執行緒無鎖佇列還是有鎖的,只不過是用了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的問題。 多執行緒無鎖佇列在開發中的使用,