場景:
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_H class 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
#include pthread.h #include#include #include #include #include #include #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 gCountArray; void* StartPthread(void* data) { for (int i = 0; i < gMaxCountTime; ++i) { // 去掉鎖的話,下邊的assert隨時crash. // 可對對象加鎖,類似objc或Java的同步關鍵字sychronized AALock::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:Usersapple2Desktop est>test gCount: 1000000 gCountArray size: 1000000 gCount: 1000000 gCountArray size: 1000000 gCount: 1000000 gCountArray size: 1000000 gCount: 1000000 gCountArray size: 1000000 gCount: 1000000 gCountArray size: 1000000 gCount: 1000000 gCountArray size: 1000000 gCount: 1000000 gCountArray size: 1000000 gCount: 1000000 gCountArray size: 1000000 gCount: 1000000 gCountArray size: 1000000 gCount: 1000000 gCountArray size: 1000000