并发高时公用锁拆分

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

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


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

template
class CMapGroup
{
    typedef typename map::iterator MAP_ITERATOR;

private:
    pthread_rwlock_t rwLock;
    pthread_rwlockattr_t rwLockAttr;

private:

    map m_objReverseAll;

    CMapGroup(const CMapGroup & obj);

public:

    short m_nGroupCount;
    CThreadSafeMap * 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[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 * GetPlainMapChildReverse(const T1 & objKey)
    {
        return & m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ].objChildReverse;
    }

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

    map * 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 & 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 & m_mapFind = m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ];

        //m_mapFind.GetWriteLock();

        map *pMap = m_mapFind.GetPlainMap();
        map *pMapReverse = m_mapFind.GetPlainMapReverse();
        map *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 & m_mapFind = m_pMaps[( (unsigned long long)objKey % m_nGroupCount ) ];

        map *pMapChildReverse = m_mapFind.GetPlainMapChildReverse();

        (*pMapChildReverse)[pObjValue_ChildReverse] = objKey;

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

};

///////////////////////////////////////////////////////////////
// end map group
///////////////////////////////////////////////////////////////

你可能感兴趣的:(C++,Linux)