サーバ設計ノート(5)---いくつかのスレッドの安全なコンテナを共有


まずはキューPipeList
 1 /*
 2  * PipeList.h
 3  *
 4  *  Created on: Aug 28, 2012
 5  *      Author: archy_yu
 6  */
 7 
 8 #ifndef PIPELIST_H_
 9 #define PIPELIST_H_
10 
11 #include <list>
12 
13 #include "Mutex.h"
14 #include "GameUtil.h"
15 
16 
17 template <class CObject>
18 class PipeList
19 {
20     friend class Player;
21     friend class EvenPlayer;
22     friend class ClientPlayer;
23 public:
24 
25     PipeList(){}
26 
27     virtual ~PipeList(){}
28 
29 /**************************************************************
30  *
31  *be careful
32  *
33  * ***********************************************************/
34 
35     int pop(CObject &_arg,BOOL swap = TRUE)
36     {
37         if(this->_read_list.empty())
38         {
39 
40             if(swap == FALSE)
41             {
42                 return -1;
43             }
44 
45             Auto_Mutex _auto_mutex(this->_mutex);
46             if(!this->_write_list.empty())
47             {
48                 this->_write_list.swap(this->_read_list);
49             }
50             else
51             {
52                 return -1;
53             }
54         }
55         _arg = this->_read_list.front();
56         this->_read_list.pop_front();
57         return 0;
58     }
59 
60     void push(CObject &_arg)
61     {
62         Auto_Mutex _auto_mutex(this->_mutex);
63         this->_write_list.push_back(_arg);
64     }
65 
66     int Size()
67     {
68         return this->_list.size();
69     }
70 
71 private:
72     void swap()
73     {
74         if(!this->_read_list.empty())
75         {
76             return;
77         }
78         Auto_Mutex _auto_mutex(this->_mutex);
79         this->_write_list.swap(this->_read_list);
80     }
81 
82 private:
83 
84     std::list<CObject> _write_list;
85 
86     std::list<CObject> _read_list;
87 
88     Mutex _mutex;
89 
90 };
91 
92 #endif /* DUPLEXLIST_H_ */

スレッドの安全なMap
     
/*
 * PipeList.h
 *
 *  Created on: Aug 28, 2012
 *      Author: archy_yu
 */

#ifndef TSMAP_H_
#define TSMAP_H_

#include <map>
#include <ext/hash_map>

using namespace __gnu_cxx;


template <class Key,class CObject>
class TsMap
{
public:

    TsMap(){}

    virtual ~TsMap(){}

    int find(Key key,CObject &_args)
    {
        Auto_R_Mutex _auto_mutex(this->_mutex);
        if(this->_map.count(key) <= 0)
        {
            return -1;
        }
        _args = this->_map.find(key)->second ;
        return 0;
    }

    int bind(Key key,CObject _args)
    {
        Auto_W_Mutex _auto_mutex(this->_mutex);
        this->_map[key] = _args;
        return 0;
    }

    int unbind(Key key)
    {
        Auto_W_Mutex _auto_mutex(this->_mutex);
        this->_map.erase(key);
        return 0;
    }
    int Size()
    {
        Auto_R_Mutex _auto_mutex(this->_mutex);
        return this->_map.size();
    }

private:

    std::map<Key,CObject> _map;

    RW_Mutex _mutex;
};

template <class Key,class CObject>
class TsHash_Map
{
public:

    TsHash_Map(){}

    virtual ~TsHash_Map(){}

    int find(Key _key,CObject &_object)
    {
        Auto_R_Mutex _auto_mutex(this->_mutex);
        if(this->_map.count(_key) <= 0)
        {
            return -1;
        }
        _object = this->_map.find(_key)->second;
        return 0;
    }

    int bind(Key _key,CObject _object)
    {
        Auto_W_Mutex _aotu_mutex(this->_mutex);
        this->_map[_key] = _object;
        return 0;
    }

    int unbind(Key _key)
    {
        Auto_W_Mutex _auto_mutex(this->_mutex);
        this->_map.erase(_key);
        return 0;
    }

    int Size()
    {
        Auto_R_Mutex _auto_mutex(this->_mutex);
        return this->_map.size();
    }

private:
    hash_map<Key,CObject> _map;
    RW_Mutex _mutex;
};

#endif

いくつかの基礎クラス
   
class Auto_R_Mutex
{
public:
    Auto_R_Mutex(RW_Mutex &rw_mutex);
    virtual ~Auto_R_Mutex();
private:
    Auto_R_Mutex();
    RW_Mutex *_mutex;
};

class Auto_W_Mutex
{
public:
    Auto_W_Mutex(RW_Mutex &rw_mutex);
    virtual ~Auto_W_Mutex();
private:
    Auto_W_Mutex();
    RW_Mutex *_mutex;
};



Auto_Mutex::Auto_Mutex(Mutex &mutex)
{
    this->_mutex = &mutex;
    this->_mutex->lock();
}
Auto_Mutex::~Auto_Mutex()
{
    this->_mutex->Release();
}



Auto_R_Mutex::Auto_R_Mutex(RW_Mutex &rw_mutex)
{
    this->_mutex = &rw_mutex;
    this->_mutex->rLock();
}
Auto_R_Mutex::~Auto_R_Mutex()
{
    this->_mutex->rRelease();
}


Auto_W_Mutex::Auto_W_Mutex(RW_Mutex &rw_mutex)
{
    this->_mutex = &rw_mutex;
    this->_mutex->wLock();
}

Auto_W_Mutex::~Auto_W_Mutex()
{
    this->_mutex->wRelease();
}

    
class RW_Mutex
{
public:

    RW_Mutex();

    virtual ~RW_Mutex();

    int rLock();

    int rRelease();

    int wLock();

    int wRelease();

private:

    pthread_rwlock_t _map_lock;

};

class Mutex
{
public:
    Mutex();

    virtual ~Mutex();

    int lock();

    int Release();

private:
    pthread_mutex_t _lock;
};






RW_Mutex::RW_Mutex()
{
    pthread_rwlock_init(&_map_lock,NULL);
}

RW_Mutex::~RW_Mutex()
{
    pthread_rwlock_destroy(&_map_lock);
}


int RW_Mutex::rLock()
{
    pthread_rwlock_rdlock(&_map_lock);
    return 0;
}

int RW_Mutex::rRelease()
{
    pthread_rwlock_unlock(&_map_lock);
    return 0;
}

int RW_Mutex::wLock()
{
    pthread_rwlock_wrlock(&_map_lock);
    return 0;
}

int RW_Mutex::wRelease()
{
    pthread_rwlock_unlock(&_map_lock);
    return 0;
}

Mutex::Mutex()
{
    pthread_mutex_init(&this->_lock,NULL);
}

Mutex::~Mutex()
{
    pthread_mutex_destroy(&this->_lock);
}

int Mutex::lock()
{
    pthread_mutex_lock(&this->_lock);
    return 0;
}

int Mutex::Release()
{
    pthread_mutex_unlock(&this->_lock);
    return 0;
}