1. 程式人生 > >一讀一寫無鎖佇列c++實現

一讀一寫無鎖佇列c++實現

限制一個執行緒讀,一個執行緒寫,不加鎖的佇列,使用單鏈表實現,測試環境: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的修改是由另一個執行緒來完成的,不會出現同時兩個執行緒修改同一個指標。