場景:
1. 開發Mac,iOS程序時,一般都會涉及到多線程開發, 比如工作線程在更新數據模型, 主線程根據數據模型來顯示界面.
比如最常用的NSMutableArray, NSMutableDictionary等, 這類集合在調用讀寫方法時並不是線程安全的,也就是說會出現數據不一致性和崩潰現象.
2. 解決辦法就是使用@syncronized()關鍵字, 有點類似Java.
test.cpp
// // main.c // test_sync // // Created by daih on 11/12/15. // Copyright (c) 2015 infoworld. All rights reserved. // #include#import #include #include pthread.h #include #include static int THREADCOUNT = 100; // 需要多線程測試的類,類裡有集合類型屬性和原始類型屬性. @interface MyDevice : NSObject { NSMutableArray* usbArray; // 集合類型 NSInteger usbCount; //原始類型 } @property(readonly) NSMutableArray* usbArray; // 原始類型可以設置原子訪問只是保證不會讀髒數據,但是不能保證算數運算的同步. // 所以還是得加鎖. @property(readwrite,assign,atomic) NSInteger usbCount; @end @implementation MyDevice @synthesize usbArray; @synthesize usbCount; -(id)init { [super init]; usbArray = [NSMutableArray new]; usbCount = 0; return self; } @end static MyDevice* gDevice = [MyDevice new]; static int gCount = 0; void* ThreadFunc(void* data) { for (int i = 0; i < 10000; ++i) { // 每次+1,注意,這裡gDevice.usbCount+1並不是原子操作,所以有可能多個線程的值是一樣的. [gDevice setUsbCount:gDevice.usbCount+1]; // 如果是多線程訪問,讀寫usbArray都需要加鎖. @synchronized(gDevice.usbArray) { [gDevice.usbArray addObject:@(i)]; } } ++gCount; return NULL; } void TestSyncVariable() { for (int i = 0; i < THREADCOUNT; ++i) { pthread_t t; pthread_create(&t,NULL,ThreadFunc,NULL); pthread_detach(t); } } int main(int argc, const char * argv[]) { // insert code here... CFShow(CFSTR(Hello, World! )); TestSyncVariable(); while (gCount != THREADCOUNT) { sleep(2); } std::cout << [gDevice.usbArray count]: << [gDevice.usbArray count] << std::endl; std::cout << gDevice.usbCount: << gDevice.usbCount << std::endl; assert(gDevice.usbCount <= [gDevice.usbArray count]); assert([gDevice.usbArray count] == THREADCOUNT*10000); CFShow(CFSTR(Bye, World! )); return 0; }
Hello, World! [gDevice.usbArray count]: 1000000 gDevice.usbCount: 999997 Bye, World! Program ended with exit code: 0