日期:2014-05-16 浏览次数:20720 次
这是我自己写的一个拥有线程安全和阻塞功能的vector类SemVector(LINUX平台),欢迎大家使用
//semvector.h #ifndef SEMVECTOR_H_ #define SEMVECTOR_H_ #include <pthread.h> #include <unistd.h> #include <semaphore.h> #include <stdio.h> template<class T> class SemVector { private: T *m_Array; //存储数据的向量 int m_Size; //向量的最大长度,-1时则没限制 int m_MaxSize; pthread_mutex_t m_Mutex; //互斥锁 sem_t m_Empty; sem_t m_Stored; public: SemVector(int size); ~SemVector(); //向vector尾部加入数据,若向量满了,则用条件变量等待 void PushBack(const T &elem); //向vector尾部删除数据,若向量为空,则用条件变量等待 T PopBack(); //返回元素 T At(int i); //返回数组的长度 int Size() { return m_Size; } //返回数组是否为空 bool Empty() { return ( 0 == m_Size ); } //返回数组的最大长度 int GetMaxSize() { return m_MaxSize; } }; template<class T> SemVector<T>::SemVector(int size) { m_MaxSize = size; m_Size = 0; m_Array = new T[size]; pthread_mutex_init(&m_Mutex, NULL); sem_init(&m_Empty, 0, size); sem_init(&m_Stored, 0, 0); } template<class T> SemVector<T>::~SemVector() { delete m_Array; pthread_mutex_destroy(&m_Mutex); sem_destroy(&m_Empty); sem_destroy(&m_Stored); } template<class T> void SemVector<T>::PushBack(const T &elem) { sem_wait(&m_Empty); pthread_mutex_lock(&m_Mutex); m_Array[m_Size++] = elem; #ifdef PRINT_DEBUG printf("push: %d, size: %d, thread: %lu\n", elem, m_Size-1, (unsigned long)pthread_self()); #endif pthread_mutex_unlock(&m_Mutex); sem_post(&m_Stored); } template<class T> T SemVector<T>::PopBack() { T res; sem_wait(&m_Stored); pthread_mutex_lock(&m_Mutex); res = m_Array[--m_Size]; #ifdef PRINT_DEBUG printf("pop : %d, size: %d, thread: %lu\n", res, m_Size, (unsigned long)pthread_self()); #endif pthread_mutex_unlock(&m_Mutex); sem_post(&m_Empty); return res; } template<class T> T SemVector<T>::At(int i) { T res; pthread_mutex_unlock(&m_Mutex); if( i < m_Size ) res = m_Array[i]; pthread_mutex_unlock(&m_Mutex); return res; } #endif
//测试例子 #define PRINT_DEBUG #include "semvector.h" SemVector<int> g_tvec(10); int g_value = 1; const int TCOUNT = 100; //生产者线程 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[TCOUNT], cusid[TCOUNT]; //产生10个生产者和10个消费者 for(int i=0; i<TCOUNT; i++) { pthread_create(&proid[i], NULL, Producer, NULL); pthread_create(&cusid[i], NULL, Customer, NULL); } for(int i=0; i<TCOUNT; i++) { pthread_join(proid[i], NULL); pthread_join(cusid[i], NULL); } return 0; }