并发高时公用锁拆分

15 篇文章 2 订阅

当并发高时,可能存在多个连接公用一个锁,当有一个卡住时,会影响其他连接速度

可以按某种规则,比如用户uid,将不同用户拆分到不同的锁上面去,临界区共享数据也同样的规则做拆分


比如根据uid,%512的值,分配到不同的map下面

template<typename T1,typename T2>
class CMapGroup
{
    typedef typename map<T1,T2>::iterator MAP_ITERATOR;

private:
    pthread_rwlock_t rwLock;
    pthread_rwlockattr_t rwLockAttr;

private:

    map<T2 *, T1> m_objReverseAll;

    CMapGroup(const CMapGroup & obj);

public:

    short m_nGroupCount;
    CThreadSafeMap<T1, T2> * m_pMaps;


    CMapGroup()
    {
        pthread_rwlockattr_init(&rwLockAttr);

        // set writing lock first
        pthread_rwlockattr_setkind_np(&rwLockAttr,PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
        if (pthread_rwlock_init(&rwLock, &rwLockAttr))
        {
            //SysLog("Init lock failed, errno: %d, line: %d", errno, __LINE__);
        }

        m_nGroupCount = 0;
        m_pMaps = 0;
    }

    CMapGroup(const short nGroupCount)
    {
        m_nGroupCount = 0;
        m_pMaps = 0;

        Init(nGroupCount);
    }

    bool GetReadLock() const
    {
        if (pthread_rwlock_rdlock((pthread_rwlock_t *)&rwLock))
        {
            //SysLog("Acquire read lock failed, errno: %d, line: %d", errno, __LINE__);
            return false;
        }

        return true;
    }

    bool GetWriteLock() const
    {
        if (pthread_rwlock_wrlock((pthread_rwlock_t *)&rwLock))
        {
            //SysLog("Acquire write lock failed, errno: %d, line: %d", errno, __LINE__);
            return false;
        }

        return true;
    }

    bool ReleaseLock() const
    {
        if (pthread_rwlock_unlock((pthread_rwlock_t *)&rwLock))
        {
            //SysLog("Release lock failed, errno: %d, line: %d", errno, __LINE__);
            return false;
        }

        return true;
    }

    unsigned int GetAllCount()
    {
        return m_objReverseAll.size();
    }

    void Init(const short nGroupCount)
    {
        if (m_pMaps)
        {
            delete [] m_pMaps;
        }

        m_nGroupCount = nGroupCount;

        if (m_nGroupCount <= 0 || m_nGroupCount > 5000)
        {
            m_nGroupCount = 512;
        }

        m_pMaps = new CThreadSafeMap<T1, T2>[m_nGroupCount];
    }

    bool GetReadLock(const T1 & objKey)
    {
        return m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ].GetReadLock();
    }

    bool GetWriteLock(const T1 & objKey)
    {
        return m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ].GetWriteLock();
    }

    bool ReleaseLock(const T1 & objKey)
    {
        return m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ].ReleaseLock();
    }

    map<T2 *,T1> * GetPlainMapChildReverse(const T1 & objKey)
    {
        return & m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ].objChildReverse;
    }

    map<T2 *,T1> * GetPlainMapReverse(const T1 & objKey)
    {
        return & m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ].objReverse;
    }

    map<T1,T2> * GetPlainMap(const T1 & objKey)
    {
        return & m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ].obj;
    }

    T2 * Find(const T1 & objKey)
    {
        return m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ].Find(objKey);
    }

    bool FindByValue(T2 * pValue)
    {
        bool bRet = false;

        GetReadLock();
        if (m_objReverseAll.find(pValue) != m_objReverseAll.end())
        {
            bRet = true;
        }
        ReleaseLock();

        return bRet;
    }

    bool FindByValue(const T1 & objKey, T2 * pValue)
    {
        //return m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ].FindByValue(pValue);

        bool bRet = false;

        GetReadLock();
        if (m_objReverseAll.find(pValue) != m_objReverseAll.end())
        {
            bRet = true;
        }
        ReleaseLock();

        return bRet;
    }

    void Erase(const T1 & objKey, T2 * pObjValue1, T2 * pObjValue2_Child)
    {
        CThreadSafeMap<T1, T2> & mapFind = m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ];

        mapFind.objChildReverse.erase(pObjValue2_Child);
        mapFind.objReverse.erase(pObjValue1);
        mapFind.obj.erase(objKey);

        // private
        GetWriteLock();
        m_objReverseAll.erase(pObjValue2_Child);
        m_objReverseAll.erase(pObjValue1);
        ReleaseLock();
    }

    T2 * SetValue(const T1 & objKey, const T2 & objValue)
    {
        CThreadSafeMap<T1, T2> & m_mapFind = m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ];

        //m_mapFind.GetWriteLock();

        map<T1, T2> *pMap = m_mapFind.GetPlainMap();
        map<T2 *,T1> *pMapReverse = m_mapFind.GetPlainMapReverse();
        map<T2 *,T1> *pMapChildReverse = m_mapFind.GetPlainMapChildReverse();

        (*pMap)[objKey] = objValue;

        MAP_ITERATOR itr = pMap->find(objKey);

        //SESSION *pSession = &itr->second;

        //pSession->SetChild();

        (*pMapReverse)[&itr->second] = objKey;

        //(*pMapChildReverse)[pSession->pObjChild] = objKey;

        //m_mapFind.ReleaseLock();

        // private
        GetWriteLock();
        m_objReverseAll[&itr->second] = objKey;
        ReleaseLock();

        return &itr->second;
    }

    void SetValue_ChildReverse(const T1 & objKey, T2 * pObjValue_ChildReverse)
    {
        CThreadSafeMap<T1, T2> & m_mapFind = m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ];

        map<T2 *,T1> *pMapChildReverse = m_mapFind.GetPlainMapChildReverse();

        (*pMapChildReverse)[pObjValue_ChildReverse] = objKey;

        // private
        GetWriteLock();
        m_objReverseAll[pObjValue_ChildReverse] = objKey;
        ReleaseLock();
    }

};

///
// end map group
///

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值