拥有线程安全和阻塞功能的vector类SemVector(LINUX平台)

来源:互联网 发布:淘宝网宋大师旗舰店 编辑:程序博客网 时间:2024/04/29 12:40

这是我自己写的一个拥有线程安全和阻塞功能的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;//向量的最大长度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_DEBUGprintf("push: %d, size: %d, thread: %lu\n", elem, m_Size-1, (unsigned long)pthread_self());#endifpthread_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_DEBUGprintf("pop : %d, size: %d, thread: %lu\n", res, m_Size, (unsigned long)pthread_self());#endifpthread_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;}