C/C++ 线程安全队列

来源:互联网 发布:glenn medeiros 知乎 编辑:程序博客网 时间:2024/06/05 08:32

一、简介

线程安全是一个比较严肃的问题,如果处理不好,可能导致数据被破坏,程序崩溃等问题,如何来处理多线程的并发问题?在windows平台有相应的api给你用于控制并发,如互斥锁,信号量,事件,临界区等,定要熟练掌握,当然现在STL库已强大到兼容不同的硬件系统了,当然对于winApi同步可以看这里:
互斥锁,信号量,事件,临界区详情

二、分析安全原理

基于conditon_variable类实现线程安全,先来看看它有什么API使

wait阻塞自己,等待唤醒wait_for阻塞自己,等待唤醒,最多等待一段时间wait_until阻塞自己,等待唤醒,最多等待到某个时间点notify_one 唤醒一个等待在这个条件变量上的线程notify_all 唤醒所有等待在这个条件变量上的线程

这个有点类似的于event,想让某处导通就直接setEvent,
某博主的关于condition_variable比较详细的讲解:点此

三、上队列代码

template<typename T> class ThreadSafe_Queue{private:    mutable mutex m_mut;    queue<T> m_queue;    condition_variable m_data_cond;public:    ThreadSafe_Queue() {}    ThreadSafe_Queue(const ThreadSafe_Queue&) = delete;    void push(T data)    {        lock_guard<mutex> lg(m_mut);        m_queue.push(data);        m_data_cond.notify_one();    }    void WaitPop(T&t)    {        unique_lock<mutex> ul(m_mut);        m_data_cond.wait(ul, [this] {return !m_queue.empty(); });        t = m_queue.front();        m_queue.pop();    }    shared_ptr<T> WaitPop()    {        unique_lock<mutex> ul(m_mut);        m_data_cond.wait(ul, [this] {return !m_queue.empty(); });        shared_ptr<T> res(make_shared<T>(m_queue.front()));        m_queue.pop();        return res;    }    bool TryPop(T &t)    {        lock_guard<mutex> lg(m_mut);        if (m_queue.empty())            return false;        t = m_queue.front();        m_queue.pop();        return true;    }    shared_ptr<T> TryPop()    {        lock_guard<mutex> lg(m_mut);        if (m_queue.empty())            return shared_ptr<T>();        shared_ptr<T> res(make_shared<T>(m_queue.front()));        m_queue.pop();        return res;    }    bool IsEmpty()    {        lock_guard<mutex> lg(m_mut);        return m_queue.empty();    }};

四、一个小例子

开了两个线程,用于测试线程队列是否安全,thread_Fuc2用于插入数据,thread_Fuc用于出队操作,经过测试,达到了安全。

ThreadSafe_Queue<int> g_queue;int g_index = 10;void thread_Fuc(){    cout << "thread_fuc1 start\n";    while (true)    {        int value=0;        g_queue.WaitPop(value);        printf("wait_and_pop done! value=%d  thread id:%d\n",value,GetCurrentThreadId());    }}void thread_Fuc2(){    cout << "thread_fuc2 start\n";    while (true)    {        Sleep(1000);        g_index++;        g_queue.push(g_index);    }}int main(){    thread thd(thread_Fuc);    thd.detach();    thread thd2(thread_Fuc2);    thd2.detach();    int a;    while (cin >> a){;}    return 0;}

测试图:
这里写图片描述


更多文章:http://blog.csdn.net/what951006?viewmode=list
powered by:小乌龟在大乌龟背上~