一讀一寫無鎖佇列c++實現
阿新 • • 發佈:2019-02-08
限制一個執行緒讀,一個執行緒寫,不加鎖的佇列,使用單鏈表實現,測試環境:centos 5.9
[[email protected] test]# cat test.cpp#include <iostream> #include <pthread.h> template<class QElmType> struct qnode { struct qnode *next; QElmType data; }; template<class QElmType> class queue { public: queue() {init();} ~queue() {destroy();} bool init() { m_front = m_rear = new qnode<QElmType>; if (!m_front) return false; m_front->next = 0; return true; } void destroy() { while (m_front) { m_rear = m_front->next; delete m_front; m_front = m_rear; } } bool push(QElmType e) { struct qnode<QElmType> *p = new qnode<QElmType>; if (!p) return false; p->next = 0; m_rear->next = p; m_rear->data = e; m_rear = p; return true; } bool pop(QElmType *e) { if (m_front == m_rear) return false; struct qnode<QElmType> *p = m_front; *e = p->data; m_front = p->next; delete p; return true; } private: struct qnode<QElmType> * volatile m_front, * volatile m_rear; }; queue<int> g_q; void *thread1(void * l) { int i = 0; while (1) { g_q.push(i); i++; usleep(::rand()%1000); } return 0; } void *thread2(void * l) { int i; while (1) { if (g_q.pop(&i)) std::cout << i << std::endl; //else //std::cout << "can not pop" << std::endl; usleep(::rand()%1000); } return 0; } int main(int argc, char* argv[]) { pthread_t t1,t2; pthread_create(&t1, 0, thread1, 0); pthread_create(&t2, 0, thread2, 0); char ch; while (1) { std::cin >> ch; if (ch == 'q') break; } return 0; }
程式碼比較簡單,只實現2個執行緒間的無鎖。
這個無鎖佇列主要是使用兩個volatile 的指標來判斷是否還有任務(volatile m_front, * volatile m_rear)。
只能實現兩個執行緒間的無鎖佇列,一個是工作者執行緒一個是提供任務執行緒,因為不能讓兩個或以上的執行緒來修改指標m_front 和指標m_rear,否者會出現問題。
這個無鎖佇列的實現是基於m_front指標的修改是由一個執行緒來完成的,m_rear的修改是由另一個執行緒來完成的,不會出現同時兩個執行緒修改同一個指標。