a sample thread safe queue

2015-04-20 刘太华 更多博文 » 博客 » GitHub »

cpp queue

原文链接 https://liutaihua.github.io/2015/04/20/a-sample-thread-safe-queue.html
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


一个自带锁的简单队列, 用单向链表实现:

template class FastQueue { struct node { T element; node * next; }; node * last; node * first; LOCK m_lock; public: FastQueue() { last = 0; first = 0; } ... // 以下暂省略

单向链表的node, 包含指向下一个node的指针next,和数据 element.
初始化队列头尾都是0, 表示空队列。

要使用这个简单的队列, 需要自带锁,自带锁的方式粒度当然是需要队列调用者控制。m_lock是自带锁的对象实例。

包含Pop, Push, front, pop_front, hasItems 我们会使用到的方法:
void Push(T elem) { m_lock.Acquire(); node * n = new node; //初始化节点 if(last) last->next = n; else first = n;
last = n;
n->next = 0; n->element = elem; m_lock.Release(); }

T Pop()
{
    m_lock.Acquire();
    if(first == 0)
    {
        m_lock.Release();
        return reinterpret_cast<T>(0);  // 空队列返回动态类型转换后的类型T
    }

    T ret = first->element;   // 非空队列, 将element提取到变量ret,
    node * td = first;        // td用来接替first, 以便删除回收Pop后的节点
    first = td->next;         // 队列首个节点,转换为Pop后节点的next指向节点
    if(!first)
        last = 0;         // 队列空了
    delete td;
    m_lock.Release();
    return ret;
}
T front()   
{
    m_lock.Acquire();
    if(first == 0)
    {
        m_lock.Release();
        return reinterpret_cast<T>(0);
    }
    T ret = first->element;
    m_lock.Release();
    return ret;
}

void pop_front()       // 删除队列最前方节点
{
    m_lock.Acquire();
    if(first == 0)
    {
        m_lock.Release();
        return;
    }
    node * td = first;
    first = td->next;
    if(!first)
        last = 0;

    delete td;
    m_lock.Release();
}

bool HasItems()      // 队列是否为空
{
    bool ret;
    m_lock.Acquire();
    ret = (first != 0);
    m_lock.Release();
    return ret;
}

{{% endhighlight %}}

一个线程安全的Mutex锁:

include

class Mutex { public: Mutex(); ~Mutex(); inline void Acquire() // 获取锁, 这是一个同步阻塞操作 { pthread_mutex_lock(&mutex); }

inline void Release()         // 释放,尝试释放一个未被获取的mutex, 不会导致错误
{
    pthread_mutex_unlock(&mutex);
}

{{% endhighlight %}}

FastQueue m_DataQueue;

创建一个自带线程安全锁的队列 m_DataQueue, 很简单的队列。