[并发并行]_[初级]_[C++实现sychronized方式的对象锁]

来源:互联网 发布:杭州it培训机构 编辑:程序博客网 时间:2024/06/03 21:44


场景:

1. 多线程程序, 数据如果在多线程间共享时, 比如数组, 基本都是需要加锁来保证安全,正确性. std库的数据结构类,如std::vector不是线程安全的, 所以读写时必须上锁.

2. objc,Java可以用sychronized来对对象加锁, 使能安全访问对象, 如果不加锁, 大多数情况下程序会崩溃.

3. 问题是无论是用 pthread_mutex_t 还是用CriticalSection, 都需要额外创建一个mutex和section来进行加锁,这样会增加很多全局变量

(需要在不同的源代码里使用锁,只能是全局变量), 使用不方便还容易出错.

4. 这里设计了一个AALock类, 功能类似synchronize 关键字, 对对象加锁. 本质就是用一个map来进行object->mutex的映射加锁.

5. pthread win32 也可以换成CriticalSection, 自己改吧.

aa_lock.h

#ifndef __AA_LOCK_H#define __AA_LOCK_Hclass  AALock{public:AALock(void* object);~AALock();static void GLock(void* object);static void GUnLock(void* object);private:void* lock_object_;};#endif


aa_lock.cpp

#include "aa_lock.h"#include "pthread.h"#include <map>typedef void* LockObject;// 重点是这里,用map来作为mutex的映射,虽然会损失点性能,但是使用方便.static std::map<void*,pthread_mutex_t> gLockObject;pthread_mutex_t gMapMutex = NULL;class AALockInternal{public:AALockInternal(){pthread_mutex_init(&gMapMutex,NULL);}~AALockInternal(){pthread_mutex_destroy(&gMapMutex);}};static AALockInternal gLockInternal;AALock::AALock(void* object){lock_object_ = object;GLock(object);}AALock::~AALock(){GUnLock(lock_object_);}void AALock::GLock(void* object){pthread_mutex_lock(&gMapMutex);pthread_mutex_t lock = NULL;if(gLockObject.find(object)!=gLockObject.end()){lock = gLockObject[object];}else{pthread_mutex_t temp = NULL;pthread_mutex_init(&temp,NULL);gLockObject[object] = temp;lock = temp;}pthread_mutex_unlock(&gMapMutex);pthread_mutex_lock(&lock);}void AALock::GUnLock(void* object){pthread_mutex_lock(&gMapMutex);pthread_mutex_t lock = NULL;lock = gLockObject[object];pthread_mutex_unlock(&gMapMutex);pthread_mutex_unlock(&lock);}

test.cpp

#include "pthread.h"#include <stdlib.h>#include <iostream>#include <stdint.h>#include <assert.h>#include <string>#include <vector>#include "aa_lock.h"static const int gMaxCountTime = 10000;static const int gTextThreadNum = 100;static pthread_t ts[gTextThreadNum];static int64_t gCount = 0;static std::vector<int> gCountArray;void* StartPthread(void* data){for (int i = 0; i < gMaxCountTime; ++i){// 去掉锁的话,下边的assert随时crash.// 可对对象加锁,类似objc或Java的同步关键字sychronizedAALock::GLock(&gCount);++gCount;AALock::GUnLock(&gCount);// 去掉锁,push_back随时崩溃,因为vector并不是线程安全的.AALock::GLock(&gCountArray);gCountArray.push_back(i);AALock::GUnLock(&gCountArray);}return NULL;}void TestAALock(){for (int i = 0; i < gTextThreadNum; ++i){pthread_create(&ts[i],NULL,StartPthread,NULL);}for (int i = 0; i < gTextThreadNum; ++i){pthread_join(ts[i],NULL);}std::cout << "gCount: " << gCount << std::endl;assert(gCount == gMaxCountTime*gTextThreadNum);std::cout << "gCountArray size: " << gCountArray.size() << std::endl; assert(gCount == gCountArray.size());}int main(int argc, char const *argv[]){for (int i = 0; i < 10; ++i){TestAALock();gCount = 0;gCountArray.clear();}return 0;}

输出:

C:\Users\apple2\Desktop\test>testgCount: 1000000gCountArray size: 1000000gCount: 1000000gCountArray size: 1000000gCount: 1000000gCountArray size: 1000000gCount: 1000000gCountArray size: 1000000gCount: 1000000gCountArray size: 1000000gCount: 1000000gCountArray size: 1000000gCount: 1000000gCountArray size: 1000000gCount: 1000000gCountArray size: 1000000gCount: 1000000gCountArray size: 1000000gCount: 1000000gCountArray size: 1000000

完整项目下载地址:

http://download.csdn.net/detail/infoworld/9327825



0 0