多线程,锁

来源:互联网 发布:mac 安装mysql详解 编辑:程序博客网 时间:2024/06/13 21:14

现在公司的代码动不动各种崩溃,原因大部分是由不加锁引起的。

例如很多的底层数据,全部封装成了AfxGetXXX的形式,对所有的类,模块全部暴露:

例如,一个缓存类,DataCache, 其中有个std::map保存数据,那么会有一个全局的AfxGetDataCache()返回这个数据结构,其中居然提供了接口std::map<CLS> &GetCache()接口,所以导致了多线程中直接操作数据引起崩溃的风险,实际也是经常会崩溃。

无奈这些东西历史已久,而且涉及太广,改动是很难了,除非有一个专门的时间来重构,现在记下来引以为戒。

并附上一段自己的代码,时刻警示自己。

</pre><pre name="code" class="cpp">#include <afxmt.h>#include <time.h>#include <stdlib.h>#include <vector>#include <atldbcli.h>class ThreadSyncClassBase;struct OpParam{    OpParam(ThreadSyncClassBase *ptest,int operate):ptest_(ptest),operate_(operate){}    ThreadSyncClassBase *ptest_;    int operate_;};class ThreadSyncClassBase{public:    ThreadSyncClassBase()    {        TCHAR lockname[20] = {};        _stprintf_s(lockname,_countof(lockname),_T("data_0x%08x"),this);        plock_data_ = new CMutex(FALSE,lockname);    }    ~ThreadSyncClassBase()    {        plock_data_->Lock();        delete plock_data_;    }    void InsertData()    {        plock_data_->Lock();        data_.push_back(rand()%1000);        plock_data_->Unlock();    }    void DeleteTailData()    {        plock_data_->Lock();        if (!data_.empty())        {            data_.erase(data_.end()-1);        }        plock_data_->Unlock();    }    int GetHeadData()    {        int ret = 0;        plock_data_->Lock();        if (!data_.empty())        {            ret = data_.front();        }        plock_data_->Unlock();        return ret;    }    //不应该出现这样的接口!!!    std::vector<int> &Datas()    {        return data_;    }        //正常可能出现的线程操作    static void OperateFunc(void *param)    {        OpParam * pparam = reinterpret_cast<OpParam*>(param);        ThreadSyncClassBase * pthis = pparam->ptest_;        int operate = pparam->operate_;        switch(operate)        {        case 0:{for(int i = 0; i < 100000; ++i){pthis->InsertData()     ;}}break;        case 1:{for(int i = 0; i < 100000; ++i){pthis->DeleteTailData() ;}}break;        case 2:{for(int i = 0; i < 100000; ++i){pthis->GetHeadData()    ;}}break;        }    }    //死锁情况    static void DeadLockTest(void *param)    {        OpParam * pparam = reinterpret_cast<OpParam*>(param);        ThreadSyncClassBase * pthis = pparam->ptest_;        pthis->plock_data_->Lock();        Sleep(10000);//        pthis->plock_data_->Unlock();//没有了    }protected:    CMutex *plock_data_;    std::vector<int> data_;};class SingleInstanceClass : public ThreadSyncClassBase{private:    SingleInstanceClass(){}    ~SingleInstanceClass(){}public:    static SingleInstanceClass *GetInstance(){if(pInst == NULL){pInst = new SingleInstanceClass;}return pInst;}    static void ReleaseInstance(){delete pInst;pInst = NULL;}private:    static SingleInstanceClass *pInst;};SingleInstanceClass *SingleInstanceClass::pInst = NULL;class MultiplyInstanceClass : public ThreadSyncClassBase{};//线程函数在类外,只读取类中的数据,线程执行过程中,类对象被释放void OuterFuncProc(void *param){    OpParam * pparam = reinterpret_cast<OpParam*>(param);    ThreadSyncClassBase * pthis = pparam->ptest_;    std::vector<int> &vct = pthis->Datas();    while(1)    {        int randnum = rand()%2;        switch(randnum)        {        case 0:{vct.push_back(rand()%1000);}break;        case 1:{if (!vct.empty()){vct.erase(vct.end()-1);}}break;        }    }}void TestThreadSyncSingleinstance(){    int count = 6;    SingleInstanceClass * pTestCls = NULL;    OpParam **opparam_array = new OpParam *[count];    HANDLE *handle_array = new HANDLE[count];    for (int i = 0; i < count; ++i)    {        pTestCls = SingleInstanceClass::GetInstance();        opparam_array[i] = new OpParam(pTestCls,i%3);        handle_array[i] = HANDLE(_beginthread(ThreadSyncClassBase::OperateFunc,0,reinterpret_cast<void*>(opparam_array[i])));        Sleep(1234);    }    //{{    OpParam paramouterlock(pTestCls,1);    _beginthread(OuterFuncProc,0,¶mouterlock);    Sleep(1000);    //}}    pTestCls->ReleaseInstance();    Sleep(10);    WaitForMultipleObjects(count,handle_array,TRUE,INFINITE);    for (int j = 0; j < count; ++j)    {        delete opparam_array[j];    }    delete[]opparam_array;    //{{TestDeadLock//     OpParam paramdeadlock(pTestCls,1);//     _beginthread(ThreadSyncClassBase::DeadLockTest,0,¶mdeadlock);//     Sleep(10);    //}}TestDeadLock    pTestCls->ReleaseInstance();    delete []handle_array;}void TestThreadSyncMultiplyinstance(){    int count = 3;    ThreadSyncClassBase **cls_array = new ThreadSyncClassBase*[count];    OpParam **opparam_array = new OpParam *[count*3];    HANDLE *handle_array = new HANDLE[count*3];    for (int i = 0; i < count; ++i)    {        cls_array[i] = new MultiplyInstanceClass;        for (int j = 0; j < 3; ++j)        {            opparam_array[i*3+j] = new OpParam(cls_array[i],j);            handle_array[i*3+j] = HANDLE(_beginthread(ThreadSyncClassBase::OperateFunc,0,reinterpret_cast<void*>(opparam_array[i*3+j])));            Sleep(1234);        }    }    WaitForMultipleObjects(count*3,handle_array,TRUE,INFINITE);    for (int j = 0; j < count*3; ++j)    {        delete opparam_array[j];    }    delete[]opparam_array;    for (int k = 0; k < count; ++k)    {        delete cls_array[k];    }    delete []cls_array;    delete []handle_array;}int main(){    srand(GetTickCount());    TestThreadSyncSingleinstance();//    TestThreadSyncMultiplyinstance();    return 0;}



0 0