多线程,锁
来源:互联网 发布: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
- #多线程锁
- 多线程&锁
- 多线程 锁
- 多线程锁
- 多线程,锁
- 【多线程】锁
- 多线程-锁
- 多线程-锁
- 多线程学习--多线程中读写锁
- C#多线程的锁
- c#多线程读写锁
- java5 多线程 锁
- 多线程,同步,锁
- 【多线程】锁的类型
- 多线程2--- 锁机制
- 多线程---读写锁
- 多线程----嵌套锁
- java多线程锁
- linux下的硬链接和软链接
- iOS开发笔记- cell里放textView根据输入的文字动态改变textView以及cell高度
- UIWebView 初学者快速入门(实现自己的第一个网页)3
- Android细节:关于开启服务Servcie
- Jenkins安装
- 多线程,锁
- Spring MVC Web关于POI导出
- 解决phpmyadmin中缺少mysqli扩展问题的方法
- JdbcDaoSupport.CLASS
- Android中AIDL
- 微信iOS 9适配总结
- 造成滑动试图卡顿原因之一:圆角
- Eclipe开发环境下的代码管理SVN
- nyu 的AI课的调度问题