GCD 信号量控制并发 (dispatch_semaphore)
dispatch_semaphore有多种用法
目前我所知道的有:
1、 防止在多个线程访问共有资源时候,会因为多线程的特性而引发数据出错的问题。
2、控制线程并发量
3、block回调是异步的,控制block 后的代码在block执行完毕后执行
在GCD中有三个函数是semaphore的操作,分别是:
dispatch_semaphore_create 创建一个semaphore
dispatch_semaphore_signal 发送一个信号
dispatch_semaphore_wait 等待信号
dispatch_semaphore_t sema = dispatch_semaphore_create(0); //创建一个信号量 参数为整型
dispatch_semaphore_signal(sema); //使信号量 sema+1
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); // 先判断sema的值 如果为0 就一直等待 如果大于0 让sema-1 然后继续执行后面的代码
1 、
在dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)和dispatch_semaphore_signal(semaphore)中间的代码,
确保了每次只有一个线程访问。
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
NSMutableArray *array = [NSMutableArrayarray];
for (int index = 0; index < 100000; index++) {
dispatch_async(queue, ^(){
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//
NSLog(@"addd :%d", index);
[array addObject:[NSNumber numberWithInt:index]];
dispatch_semaphore_signal(semaphore);
});
}
2、
创建了一个初使值为10的semaphore,每一次for循环都会创建一个新的线程,
线程结束的时候会发送一个信号,线程创建之前会信号等待,所以当同时创建了10个线程之后,
for循环就会阻塞,等待有线程结束之后会增加一个信号才继续执行,如此就形成了对并发的控
制,如上就是一个并发数为10的一个线程队列。
dispatch_group_t group = dispatch_group_create();
dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < 100; i++)
{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_group_async(group, queue, ^{
NSLog(@"%i",i);
sleep(2);
dispatch_semaphore_signal(semaphore);
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_release(group);
dispatch_release(semaphore);
3、
在block回调执行完毕后,才继续执行block后的代码
__block BOOL isok = NO;
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
Engine *engine = [[Engine alloc] init];
[engine queryCompletion:^(BOOL isOpen) {
isok = isOpen;
dispatch_semaphore_signal(sema);
} onError:^(int errorCode, NSString *errorMessage) {
isok = NO;
dispatch_semaphore_signal(sema);
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);