[并发并行]_[初级]_[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
#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
- [并发并行]_[初级]_[C++实现sychronized方式的对象锁]
- [并发并行]_[线程同步]_[C/C++实现单例模式分析]
- [并发并行]_[中级]_[实现Pthread线程并发读写锁rwlock]
- [并发并行]_[C/C++]_[C++标准库里的线程安全问题]
- [并发并行]_[Object-C]_[使用NSMutableArray等非线程安全集合类的注意事项]
- [并发并行]_[pthread]_[线程池的简单设计与实现]
- [并发并行]_[线程池]_[Programming With POSIX Threads的线程池实现分析1]
- [并发并行]_[Windows]_[指定程序执行的CPU]
- [C/C++标准库]_[初级]_[函数对象functor的使用]
- [Object-C]_[初级]_[object类的对象和属性@property]
- [并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)调用复制文件接口的案例]
- JAVA并发编程1_多线程的实现方式
- [C/C++]_[初级]_[malloc-calloc-new的区别]
- [C/C++]_[初级]_[编程容易犯错的地方]
- [C/C++标准库]_[初级]_[获取文件的所在目录跨平台实现]
- [C/C++标准库]_[初级]_[如何实现std::string自己的Format(sprintf)函数]
- [ATL/WTL]_[初级]_[常用的界面对象操作]
- [Object c]_[初级]_[NSString常用方法的总结]
- 2015年12月4日工作总结
- VIJOS-P1033
- NOIP2015提高组day2 —— 跳石头(stone)
- 计蒜客—爱奇异的自制节目
- 又鼓捣起刚毕业时玩的东西了
- [并发并行]_[初级]_[C++实现sychronized方式的对象锁]
- Install SVN Error:The Feature You Are Tring to Use is on a Network Resource That is Unvaliable
- 贪心——POJ1328
- Android 控件之DatePicker(日期和日历)
- linux 信号安装、signal、kill,arise讲解
- openfire的安装和配置
- iOS网络底层之CFNetwok
- linux 信号处理流程
- 阿里云Unbuntu 命令行vpn连接