一、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