dispatch_semaphore_create
dispatch_semaphore_create(long value)
传入的是一个数字,该数字必须大于等于0。列如传入10,表示创建一个信号总量为10信号量(就好比一共有10个停车位)。假如传入0
The starting value for the semaphore. Passing a value less than zero will cause NULL to be returned.
则返回为NULL
dispatch_semaphore_wait
该函数会使传入的信号量减1,当信号量有 >= 1时,就会继续往下执行。如果没有,该线程就会一直处于等待状态,可阻塞当前线程。该函数需要传入另一个参数
#define DISPATCH_TIME_NOW 表示从现在开始 #define DISPATCH_TIME_FOREVER 表示永不超时
dispatch_semaphore_single
该函数会使传入的信号量加1,与dispatch_ semaphore _ wait
成对出现。
拿YYKit源码来举例:在#import “UIButton+YYWebImage.m”中
1 | - (instancetype)init { |
在读取_YYWebImageSetter该函数中使用dispatch_semaphore_wait
和dispatch_semaphore_signal
使当前函数为线程安全。实际上信号量就是锁,它与 @synchronized
函数看起来很像。所起到的作用就是至始至终只会有一个线程去访问该函数。
在 这边文章中很形象的比喻了信号量
1 | 关于信号量,一般可以用停车来比喻。 |
举个🌰 NSMutableArray不是线程安全的,我们可以稍作修饰,线程安全的去更新数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14NSMutableArray *array = [NSMutableArray array];
dispatch_semaphore_t semphore = dispatch_semaphore_create(1);
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.lx.gcddemo",DISPATCH_QUEUE_CONCURRENT);
dispatch_apply(100, concurrentQueue, ^(size_t i) {
dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
/*
@synchronized (array) {
[array addObject:[NSNumber numberWithUnsignedInteger:i]];
}
*/
[array addObject:[NSNumber numberWithUnsignedInteger:i]];
dispatch_semaphore_signal(semphore);
});
NSLog(@"%@",array);