日期:2014-05-16  浏览次数:20660 次

Linux下设计并发队列

设计并发队列

#include <pthread.h>
#include <list>
using namespace std;

template <typename T>
class Queue 
{ 
public: 
    Queue( ) 
    { 
        pthread_mutex_init(&_lock, NULL); 
    } 
    ~Queue( ) 
    { 
        pthread_mutex_destroy(&_lock);
    } 
    void push(const T& data);
    T pop( ); 
private: 
    list<T> _list; 
    pthread_mutex_t _lock;
};

template <typename T>
void Queue<T>::push(const T& value ) 
{ 
    pthread_mutex_lock(&_lock);
    _list.push_back(value);
    pthread_mutex_unlock(&_lock);
}

template <typename T>
T Queue<T>::pop( ) 
{ 
    if (_list.empty( )) 
    { 
        throw "element not found";
    }
    pthread_mutex_lock(&_lock); 
    T _temp = _list.front( );
    _list.pop_front( );
    pthread_mutex_unlock(&_lock);
    return _temp;
}

上述代码是有效的。但是,请考虑这样的情况:您有一个很长的队列(可能包含超过 100,000 个元素),而且在代码执行期间的某个时候,从队列中读取数据的线程远远多于添加数据的线程。因为添加和取出数据操作使用相同的互斥锁,所以读取数据的速度会影响写数据的线程访问锁。那么,使用两个锁怎么样?一个锁用于读取操作,另一个用于写操作。给出修改后的 Queue 类。

template <typename T>
class Queue 
{ 
public: 
    Queue( ) 
    { 
        pthread_mutex_init(&_rlock, NULL); 
        pthread_mutex_init(&_wlock, NULL);
    } 
    ~Queue( ) 
    { 
        pthread_mutex_destroy(&_rlock);
        pthread_mutex_destroy(&_wlock);
    } 
    void push(const T& data);
    T pop( ); 
private: 
    list<T> _list; 
    pthread_mutex_t _rlock, _wlock;
};


template <typename T>
void Queue<T>::push(const T& value ) 
{ 
    pthread_mutex_lock(&_wlock);
    _list.push_back(value);
    pthread_mutex_unlock(&_wlock);
}

template <typename T&g