C++:基於標準容器map的多線程安全的map容器(本身的類做key和value時,慎用)

//mymap.h
//使用該map的方式:包含該頭文件便可使用
#ifndef _WDMAP_MYMAP_H_
#define _WDMAP_MYMAP_H_
  
#if defined  _WIN32                                                         //Windows
#include <Windows.h>
#define MyMap_CLock_Mutex_t                 HANDLE
#define MyMap_CLock_Mutex_Init(_mutex)      (_mutex = CreateSemaphore(NULL,1,1,NULL))
#define MyMap_CLock_Mutex_Lock(_mutex)      (WaitForSingleObject(_mutex, INFINITE))
#define MyMap_CLock_Mutex_UnLock(_mutex)    (ReleaseSemaphore(_mutex,1,NULL))
#define MyMap_CLock_Mutex_Destroy(_mutex)   (CloseHandle(_mutex))
#define MyMap_Declar_Typename               typename
#define MyMap_Type_Typename
  
#elif defined __linux                                                       //Linux
#include <pthread.h>
#define MyMap_CLock_Mutex_t                 pthread_mutex_t
#define MyMap_CLock_Mutex_Init(_mutex)      (pthread_mutex_init(&_mutex, NULL))
#define MyMap_CLock_Mutex_Lock(_mutex)      (pthread_mutex_lock(&_mutex))
#define MyMap_CLock_Mutex_UnLock(_mutex)    (pthread_mutex_unlock(&_mutex))
#define MyMap_CLock_Mutex_Destroy(_mutex)   (pthread_mutex_destroy(&_mutex))
#define MyMap_Declar_Typename 
#define MyMap_Type_Typename                 typename
#endif
  
#include <map>
  
namespace wdmap
{
    //my iterator                                                           
    template<class K, class V>
    class WDItr
    {
    public:
        WDItr();
        WDItr(const std::map<K, V>& t_map);
        WDItr(const WDItr& val);
        ~WDItr();
  
  
        //************************************
        // Method:    operator
        // FullName:  operator
        // Access:    public 
        // Returns:   
        // Qualifier: 迭代器沒有實現自減運算符重載
        // Parameter: 
        //************************************
        WDItr<K, V>& operator=(const WDItr& val);
        WDItr<K, V>& operator++(int);
        bool operator==(const WDItr& val);
        bool operator!=(const WDItr& val);
        WDItr<K, V>& operator++();
  
    public:
        bool _isEnd;
  
        K first;
        V second;
  
    private:
        std::map<K, V> _tempMap;
  
        WDItr<K, V>* _oldSelf;
    };
  
    template<class K, class V>
    bool wdmap::WDItr<K, V>::operator!=( const WDItr& val )
    {
        return !(*this == val);
    }
    template<class K, class V>
    WDItr<K, V>& wdmap::WDItr<K, V>::operator++()
    {
        MyMap_Type_Typename std::map<K, V>::iterator _mitr = _tempMap.find(this->first);
  
        if(_mitr == _tempMap.end() || ++_mitr == _tempMap.end())
        {
            this->_isEnd = true;
  
            return *this;
        }
  
        this->_isEnd = false;
        this->first = _mitr->first;
        this->second = _mitr->second;
  
        return *this;
    }
  
    template<class K, class V>
    bool wdmap::WDItr<K, V>::operator==( const WDItr& val )
    {
        if(this->_isEnd == true && val._isEnd == true)
        {
            return true;
        }
  
        if(this->_isEnd == val._isEnd && this->first == val.first)
        {
            return true;
        }
  
        return false;
    }
    template<class K, class V>
    WDItr<K, V>& wdmap::WDItr<K, V>::operator++( int )
    {
        if(this->_oldSelf)
        {
            delete this->_oldSelf;
            this->_oldSelf = NULL;
        }
  
        this->_oldSelf = new WDItr<K, V>(*this);
  
        ++(*this);
  
        return *(this->_oldSelf);
    }
    template<class K, class V>
    WDItr<K, V>& wdmap::WDItr<K, V>::operator=( const WDItr& val )
    {
        if(this == &val)
        {
            return *this;
        }
  
        this->first = val.first;
        this->second = val.second;
        this->_isEnd = val._isEnd;
        this->_tempMap = val._tempMap;
        this->_oldSelf = NULL;
  
        if(val._oldSelf)
        {
            this->_oldSelf = new WDItr<K, V>(*val._oldSelf);
        }
  
        return *this;
    }
    template<class K, class V>
    wdmap::WDItr<K, V>::WDItr( const WDItr& val )
    {
        this->first = val.first;
        this->second = val.second;
        this->_isEnd = val._isEnd;
        this->_tempMap = val._tempMap;
        this->_oldSelf = NULL;
  
        if(val._oldSelf)
        {
            this->_oldSelf = new WDItr<K, V>(*val._oldSelf);
        }
    }
    template<class K, class V>
    wdmap::WDItr<K, V>::WDItr( const std::map<K, V>& t_map )
    {
        this->_isEnd = true;
       this->_tempMap = t_map;
        this->_oldSelf = NULL;
    }
    template<class K, class V>
    wdmap::WDItr<K, V>::~WDItr()
    {
        if(this->_oldSelf)
        {
            delete this->_oldSelf;
            this->_oldSelf = NULL;
        }
    }
    template<class K, class V>
    wdmap::WDItr<K, V>::WDItr()
    {
        this->_isEnd = true;
        this->_oldSelf = NULL;
    }
  
    //lock
    class CLock  
    {  
    public: 
        CLock(){MyMap_CLock_Mutex_Init(_mutex);}
        ~CLock(){MyMap_CLock_Mutex_Destroy(_mutex);}
  
        void Lock() {MyMap_CLock_Mutex_Lock(_mutex);}
        void UnLock() {MyMap_CLock_Mutex_UnLock(_mutex);}
  
    private:
        MyMap_CLock_Mutex_t _mutex;
    };  
  
    //map
    template<class K, class V>
    class map
    {
    public:
        map(void);
        map(const map& val);
        ~map(void);
  
        typedef MyMap_Declar_Typename WDItr<K, V> iterator;
        typedef unsigned int size_type;
  
        V& operator[](const K& t_key);
        map& operator=(const map& val);
  
    public:
        iterator begin();
        iterator end();
  
        void insert(const K t_key, const V t_val);
        iterator find(const K t_key);
        void erase(const K t_key);
        void erase(const iterator _val);
        bool update(const K t_key, const V t_val);
        bool update(const iterator _val);
  
        size_type size();
  
    private:
        std::map<K, V> _wdmap;
  
        CLock _myLock;
    };
  
    template<class K, class V>
    wdmap::map<K, V>& wdmap::map<K, V>::operator=( const map& val )
    {
        if(this == &val)
        {
            return *this;
        }
  
        this->_myLock.Lock();
        val._myLock.Lock();
  
        this->_wdmap = val._wdmap;
  
        val._myLock.UnLock();
        this->_myLock.UnLock();
  
        return *this;
    }
    template<class K, class V>
    wdmap::map<K, V>::map( const map& val )
    {
        val._myLock.Lock();
  
        this->_wdmap = val._wdmap;
  
        val._myLock.UnLock();
    }
    template<class K, class V>
    V& wdmap::map<K, V>::operator[]( const K& t_key )
    {
        this->_myLock.Lock();
  
        MyMap_Type_Typename std::map<K, V>::iterator _mitr = this->_wdmap.find(t_key);
        if(_mitr == this->_wdmap.end())
        {
            this->_wdmap.insert(MyMap_Type_Typename std::map<K, V>::value_type(t_key, V()));
             _mitr = this->_wdmap.find(t_key);
        }
  
        this->_myLock.UnLock();
  
        return _mitr->second;
    }
  
    template<class K, class V>
    typename wdmap::map<K, V>::size_type wdmap::map<K, V>::size()
    {
        this->_myLock.Lock();
  
        wdmap::map<K, V>::size_type m_size = this->_wdmap.size();
  
        this->_myLock.UnLock();
  
        return m_size;
    }
    //************************************
    // Method:    update
    // FullName:  wdmap::map<K, V>::update
    // Access:    public 
    // Returns:   bool
    // Qualifier: 經過iterator更新map中具備的first key的value值,若無該key,則返回false
    // Parameter: const iterator _val
    //************************************
    template<class K, class V>
    bool wdmap::map<K, V>::update( const iterator _val )
    {
        return update(_val.first, _val.second);
    }
    //************************************
    // Method:    update
    // FullName:  wdmap::map<K, V>::update
    // Access:    public 
    // Returns:   bool
    // Qualifier: 經過key和value更新map中具備的key的value值,若無該key,則返回false
    // Parameter: const K t_key
    // Parameter: const V t_val
    //************************************
    template<class K, class V>
    bool wdmap::map<K, V>::update( const K t_key, const V t_val )
    {
        this->_myLock.Lock();
  bool ret = false;
        MyMap_Type_Typename std::map<K, V>::iterator _mitr = this->_wdmap.find(t_key);
        if(_mitr != this->_wdmap.end())
        {
            _mitr->second = t_val;
   ret = true;
        }
  
        this->_myLock.UnLock();
  
        return ret;
    }
    template<class K, class V>
    void wdmap::map<K, V>::erase( const  iterator _val )
    {
        this->_myLock.Lock();
  
        this->_wdmap.erase(_val.first);
  
        this->_myLock.UnLock();
    }
    template<class K, class V>
    void wdmap::map<K, V>::erase( const K t_key )
    {
        this->_myLock.Lock();
  
        this->_wdmap.erase(t_key);
  
        this->_myLock.UnLock();
    }
    //************************************
    // Method:    find
    // FullName:  wdmap::map<K, V>::find
    // Access:    public 
    // Returns:   ::iterator
    // Qualifier: 經過key進行查找,若沒有查找到,則返回end
    // Parameter: const K t_key
    //************************************
    template<class K, class V>
    typename wdmap::map<K, V>::iterator wdmap::map<K, V>::find( const K t_key )
    {
        this->_myLock.Lock();
  
        wdmap::map<K, V>::iterator _tmpItr(this->_wdmap);
  
        MyMap_Type_Typename std::map<K, V>::iterator _mitr = this->_wdmap.find(t_key);
        if(_mitr != this->_wdmap.end())
        {
            _tmpItr._isEnd = false;
            _tmpItr.first = _mitr->first;
            _tmpItr.second = _mitr->second;
        }
  
        this->_myLock.UnLock();
  
        return _tmpItr;
    }
    //************************************
    // Method:    insert
    // FullName:  wdmap::map<K, V>::insert
    // Access:    public 
    // Returns:   
    // Qualifier: 插入key,value
    // Parameter: const K t_key
    // Parameter: const V t_val
    //************************************
    template<class K, class V>
    void wdmap::map<K, V>::insert( const K t_key, const V t_val )
    {
        this->_myLock.Lock();
  
        this->_wdmap.insert(MyMap_Type_Typename std::map<K, V>::value_type(t_key, t_val));
  
        this->_myLock.UnLock();
  
        return ;
    }
    template<class K, class V>
    typename wdmap::map<K, V>::iterator wdmap::map<K, V>::end()
    {
        wdmap::map<K, V>::iterator _tmpItr;
  
        return _tmpItr;
    }
    template<class K, class V>
    typename wdmap::map<K, V>::iterator wdmap::map<K, V>::begin()
    {
        this->_myLock.Lock();
  
        wdmap::map<K, V>::iterator _tmpItr(this->_wdmap);
  
        MyMap_Type_Typename std::map<K, V>::iterator _mitr = this->_wdmap.begin();
        if(_mitr != this->_wdmap.end())
        {
            _tmpItr._isEnd = false;
            _tmpItr.first = _mitr->first;
            _tmpItr.second = _mitr->second;
        }
  
        this->_myLock.UnLock();
  
        return _tmpItr;
    }
    template<class K, class V>
    wdmap::map<K, V>::~map( void )
    {
    }
    template<class K, class V>
    wdmap::map<K, V>::map( void )
    {
    }
}
  
#endif

    1.win下vs平臺測試本身的map代碼(基於boost中的建立線程函數)

// TestMyMap.cpp : 定義控制檯應用程序的入口點。
//

#include "stdafx.h"
#include "stdafx.h"
#include <boost/lockfree/queue.hpp>
#include <boost/atomic.hpp>
#include <boost/thread/thread.hpp>
#include <iostream>
#include <Windows.h>
#include "../MyMap/map.h"

using namespace std;

const int producer_thread_count = 4;  
const int consumer_thread_count = 4;  
const int reader_thread_count = 4;  
const int update_thread_count = 4; 

const int times = 1000;

typedef wdmap::map< unsigned int,unsigned long>  MSG_MAP;

MSG_MAP test_Map;

void producer(void) 
{
	static int k=0;
	for (int i = 1; ;i++)
	{
		unsigned long data = i;
		test_Map.insert(i,data);

		//std::cout<<k++<<std::endl;
	}
}

void consumer(void)
{
	for (int i = 1; ;i++)
	{
		test_Map.erase(i);
	}
}

void reader(void)
{
	while(1)
	{
		MSG_MAP::iterator _beginItr = test_Map.begin();
		for (; _beginItr != test_Map.end();_beginItr++)
		{
			//test_Map.erase(_beginItr++);
		}

		std::cout<<"size:"<<test_Map.size()<<std::endl;
		//std::cout<<"test_Map.begin():"<<test_Map.begin().second<<std::endl;
	}
}

void update(void)
{
	while(1)
	{
		MSG_MAP::iterator _beginItr = test_Map.begin();
		for (; _beginItr != test_Map.end();_beginItr++)
		{
			_beginItr.second = 1200;
			test_Map.update(_beginItr);

			//MSG_MAP::iterator _findItr = test_Map.find(_beginItr.first);

			//std::cout<<_findItr.second<<std::endl;
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	boost::thread_group producer_threads, consumer_threads, _reader, _update;  

	for (int i = 0; i != producer_thread_count; ++i)  
		producer_threads.create_thread(producer);  

	for (int i = 0; i != consumer_thread_count; ++i)  
		consumer_threads.create_thread(consumer);  

	for (int i = 0; i != reader_thread_count; ++i)  
		_reader.create_thread(reader);  

	for (int i = 0; i != update_thread_count; ++i)  
		_reader.create_thread(update);  


	producer_threads.join_all();  

	consumer_threads.join_all();  

	_reader.join_all();
	_update.join_all();

	cout<<"done"<<endl;

	return 0;
}

      

  2.Linux下eclipse平臺測試本身的map的代碼 linux

//============================================================================
// Name        : TestWDMap.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C, Ansi-style
//============================================================================

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>

#include "map.h"

#define counts 2000

#define wthreadNum 4			//寫線程個數
#define rthreadNum 4			//讀線程個數
#define ethreadNum 4			//擦拭線程個數
#define uthreadNum 4			//更新線程個數
#define fthreadNum 4			//查找線程個數

typedef wdmap::map<int, int> MYMAP_t;

MYMAP_t _myMap;

void* write(void* arg)
{
	while(1)
	{
		for(int i=0; i<counts; i++)
		{
			_myMap.insert(i, i);
		}
	}

	return NULL;
}

void* read(void* arg)
{
	while(1)
	{
		MYMAP_t::iterator _beginItr = _myMap.begin();

		for(; _beginItr!=_myMap.end(); _beginItr++)
		{

		}

		std::cout<<"_myMap.begin value:"<<_myMap.begin().second<<std::endl;

		std::cout<<"size:"<<_myMap.size()<<std::endl;
	}

	return NULL;
}

void* erase(void* arg)
{
	while(1)
	{
		for(int i=0; i<counts; i++)
		{
			_myMap.erase(i);
		}
	}

	return NULL;
}

void* update(void* arg)
{
	while(1)
	{
		for(int i=0; i<counts; i++)
		{
			_myMap.update(i, 1200);
		}

	}

	return NULL;
}

void* find(void* arg)
{
	while(1)
	{
		for(int i=0; i<counts; i++)
		{
			_myMap.find(i);
		}
	}

	return NULL;
}

int main(void)
{
	pthread_t _theadId[wthreadNum + rthreadNum + ethreadNum + uthreadNum + fthreadNum];

	for(int i=0; i<wthreadNum + rthreadNum + ethreadNum + uthreadNum + fthreadNum; i++)
	{
		if(i < wthreadNum)
		{
			pthread_create(&_theadId[i], NULL, write, NULL);
		}
		else if(i < wthreadNum + rthreadNum)
		{
			pthread_create(&_theadId[i], NULL, read, NULL);
		}
		else if(i < wthreadNum + rthreadNum + ethreadNum)
		{
			pthread_create(&_theadId[i], NULL, erase, NULL);
		}
		else if(i < wthreadNum + rthreadNum + ethreadNum + uthreadNum)
		{
			pthread_create(&_theadId[i], NULL, update, NULL);
		}
		else
		{
			pthread_create(&_theadId[i], NULL, find, NULL);
		}
	}

	pthread_join(_theadId[wthreadNum + rthreadNum + ethreadNum + uthreadNum + fthreadNum - 1], NULL);

	return EXIT_SUCCESS;
}

相關文章
相關標籤/搜索