23,116
社区成员
发帖
与我相关
我的任务
分享
#include <iostream>
#include <vector>
#include <string>
using namespace std;
#include <pthread.h>
#include <unistd.h>
template<class T>
class ThreadSafeVector
{
public:
ThreadSafeVector(int size = -1);
~ThreadSafeVector();
//向vector尾部加入数据,若向量满了,则用条件变量等待
void PushBack(const T &elem);
//向vector尾部删除数据,若向量为空,则用条件变量等待
T PopBack();
int Size();
bool Empty();
T At(int i);
void SetMaxSize(int maxSize);
int GetMaxSize();
private:
//存储数据的向量
vector<T> m_Vector;
//互斥锁
pthread_mutex_t *m_Mutex;
//向量满时的条件变量
pthread_cond_t *m_Full_Cond;
//向量空时的条件变量
pthread_cond_t *m_Empty_Cond;
//向量的最大长度,-1时则没限制
int m_MaxSize;
};
template<class T>
ThreadSafeVector<T>::ThreadSafeVector(int size)
{
m_Mutex = new pthread_mutex_t;
m_Full_Cond = new pthread_cond_t;
m_Empty_Cond = new pthread_cond_t;
pthread_mutex_init(m_Mutex, NULL);
pthread_cond_init(m_Full_Cond, NULL);
pthread_cond_init(m_Empty_Cond, NULL);
m_MaxSize = size;
}
template<class T>
ThreadSafeVector<T>::~ThreadSafeVector()
{
pthread_mutex_destroy(m_Mutex);
pthread_cond_destroy(m_Full_Cond);
pthread_cond_destroy(m_Empty_Cond);
delete m_Mutex;
delete m_Empty_Cond;
delete m_Full_Cond;
}
template<class T>
void ThreadSafeVector<T>::PushBack(const T &elem)
{
pthread_mutex_lock(m_Mutex);
//若向量为空,则唤醒某个消费者线程
if( m_Vector.empty() )
pthread_cond_signal(m_Empty_Cond);
//若向量满了,则将自身线程投入等待
while( m_MaxSize != -1 &&
m_Vector.size() == m_MaxSize )
pthread_cond_wait(m_Full_Cond, m_Mutex);
m_Vector.push_back(elem);
cout << "tid: " << pthread_self() << " Push: " << elem << " All: " << m_Vector.size() << endl;
pthread_mutex_unlock(m_Mutex);
}
template<class T>
T ThreadSafeVector<T>::PopBack()
{
pthread_mutex_lock(m_Mutex);
//若向量满了,则唤醒某个生产者线程
if( m_Vector.size() == m_MaxSize )
pthread_cond_signal(m_Full_Cond);
//若向量为空,则将自身线程投入等待
while( m_Vector.empty() )
pthread_cond_wait(m_Empty_Cond, m_Mutex);
int size = m_Vector.size();
T res = m_Vector[size-1];
cout << "tid: " << pthread_self() << " Pop: " << res << " All: " << m_Vector.size() << endl;
m_Vector.pop_back();
pthread_mutex_unlock(m_Mutex);
return res;
}
template<class T>
T ThreadSafeVector<T>::At(int i)
{
T res;
pthread_mutex_unlock(m_Mutex);
if( i < m_Vector.size() )
res = m_Vector[i];
pthread_mutex_unlock(m_Mutex);
return res;
}
template<class T>
void ThreadSafeVector<T>::SetMaxSize(int maxSize)
{
pthread_mutex_lock(m_Mutex);
if( m_Vector.size() > maxSize )
{
int len = m_Vector.size() - maxSize;
for(int i=0; i<len; i++)
m_Vector.pop_back();
}
pthread_mutex_unlock(m_Mutex);
}
template<class T>
int ThreadSafeVector<T>::GetMaxSize()
{
return m_MaxSize;
}
template<class T>
int ThreadSafeVector<T>::Size()
{
pthread_mutex_lock(m_Mutex);
int res = m_Vector.size();
pthread_mutex_unlock(m_Mutex);
return res;
}
template<class T>
bool ThreadSafeVector<T>::Empty()
{
pthread_mutex_lock(m_Mutex);
bool res = m_Vector.empty();
pthread_mutex_unlock(m_Mutex);
return res;
}
//////////////////////////////////////////////////////////////////////////
ThreadSafeVector<int> g_tvec(10);
int g_value = 1;
//生产者线程
void *Producer(void *arg)
{
while(1)
{
g_tvec.PushBack(g_value++);
}
}
//消费者线程
void *Customer(void *arg)
{
while(1)
{
g_tvec.PopBack();
}
}
int main()
{
pthread_t proid[10], cusid[10];
//产生10个生产者和10个消费者
for(int i=0; i<10; i++)
{
pthread_create(&proid[i], NULL, Producer, NULL);
pthread_create(&cusid[i], NULL, Customer, NULL);
}
for(int i=0; i<10; i++)
{
pthread_join(proid[i], NULL);
pthread_join(cusid[i], NULL);
}
return 0;
}