一、NSCondition是对条件变量和互斥量的一个封装,用于线程之间的同步。
其中的互斥量用于保护对条件变量的修改,条件变量变化以信号量的方式通知其它线程实现线程之间的同步。
二、NSCondition的API
NSCondition实现了NSLocking协议,这个协议定义了lock和unlock方法,用于多个线程互斥得执行一段代码,以保护共享的数据。
同时,NSCondition还包含以下方法:
- (void)wait;
- (BOOL)waitUntilDate:(NSDate *)limit;
- (void)signal;
- (void)broadcast;
wait:释放互斥量,使当前线程等待,切换到其它线程执行。
waitUntilDate:释放互斥量,使当前线程等待到某一个时间,切换到其它线程执行。
signal:唤醒一个其它等待该条件变量的线程
broadcast:唤醒所有其它等待该条件变量的线程
三、demo
下面的例子来源于网络,对其做了一点修改
1 int main(int argc, const char * argv[]) { 2 @autoreleasepool { 3 // insert code here... 4 5 NSConditionSample *sample = [[NSConditionSample alloc] init]; 6 7 [NSThread detachNewThreadSelector:@selector(createConsumenr) 8 toTarget:sample 9 withObject:nil]; 10 11 [NSThread detachNewThreadSelector:@selector(createProducter) 12 toTarget:sample 13 withObject:nil]; 14 15 16 17 18 19 20 21 getchar(); 22 } 23 return 0; 24 }
下面是生产者、消费者:
1 #import "NSConditionSample.h" 2 3 @interface NSConditionSample () 4 { 5 NSCondition *condition; 6 NSMutableArray *products; 7 } 8 9 @end 10 11 12 @implementation NSConditionSample 13 14 - (instancetype)init 15 { 16 if(self = [super init]) 17 { 18 condition = [[NSCondition alloc] init]; 19 products = [[NSMutableArray alloc] init]; 20 } 21 return self; 22 } 23 24 25 - (void)createConsumenr 26 { 27 while (YES) { 28 NSLog(@"createConsumenr before lock"); 29 [condition lock]; 30 NSLog(@"createConsumenr after lock"); 31 while ([products count] == 0) { 32 NSLog(@"wait for products"); 33 [condition wait]; 34 } 35 [products removeObjectAtIndex:0]; 36 NSLog(@"comsume a product"); 37 [condition unlock]; 38 } 39 } 40 41 - (void)createProducter 42 { 43 while (YES) { 44 NSLog(@"createProducter before lock"); 45 [condition lock]; 46 NSLog(@"createProducter after lock"); 47 [products addObject:[[NSObject alloc] init]]; 48 NSLog(@"produce a product"); 49 [condition signal]; 50 [condition unlock]; 51 } 52 53 } 54 55 @end
执行的log:
2015-07-24 11:05:48.374 NSConditionSample[45259:40628634] createConsumenr before lock
2015-07-24 11:05:48.374 NSConditionSample[45259:40628635] createProducter before lock
2015-07-24 11:05:48.374 NSConditionSample[45259:40628634] createConsumenr after lock
2015-07-24 11:05:48.375 NSConditionSample[45259:40628634] wait for products
2015-07-24 11:05:48.375 NSConditionSample[45259:40628635] createProducter after lock
2015-07-24 11:05:48.375 NSConditionSample[45259:40628635] produce a product
2015-07-24 11:05:48.375 NSConditionSample[45259:40628635] createProducter before lock
2015-07-24 11:05:48.375 NSConditionSample[45259:40628634] comsume a product
2015-07-24 11:05:48.375 NSConditionSample[45259:40628634] createConsumenr before lock
2015-07-24 11:05:48.375 NSConditionSample[45259:40628635] createProducter after lock
2015-07-24 11:05:48.375 NSConditionSample[45259:40628635] produce a product
2015-07-24 11:05:48.375 NSConditionSample[45259:40628634] createConsumenr after lock
2015-07-24 11:05:48.375 NSConditionSample[45259:40628635] createProducter before lock
2015-07-24 11:05:48.375 NSConditionSample[45259:40628634] comsume a product
2015-07-24 11:05:48.376 NSConditionSample[45259:40628634] createConsumenr before lock
2015-07-24 11:05:48.376 NSConditionSample[45259:40628635] createProducter after lock
2015-07-24 11:05:48.376 NSConditionSample[45259:40628635] produce a product
2015-07-24 11:05:48.376 NSConditionSample[45259:40628634] createConsumenr after lock
2015-07-24 11:05:48.376 NSConditionSample[45259:40628635] createProducter before lock
2015-07-24 11:05:48.376 NSConditionSample[45259:40628634] comsume a product
2015-07-24 11:05:48.390 NSConditionSample[45259:40628634] createConsumenr before lock
2015-07-24 11:05:48.390 NSConditionSample[45259:40628635] createProducter after lock
2015-07-24 11:05:48.390 NSConditionSample[45259:40628635] produce a product