美文网首页
关于GCD的dispatch_semaphore_t

关于GCD的dispatch_semaphore_t

作者: logke | 来源:发表于2017-05-25 16:45 被阅读0次

当需要处理资源竞争,可以借用GCD的信号机制

  • dispatch_semaphore_create(long value); 创建一个信号资源,参数值value大于等于0,当value = 1表示当前资源是1,value=0表示没有资源
  • dispatch_semaphore_wait(dispatch_semaphore_t dsema,dispatch_time_t timeout); 等待(减少)信号资源,如果信号资源<=0,将一直等待知道资源大于0;
  • dispatch_semaphore_signal(dispatch_semaphore_t dsema); 产生发送(增加)信号资源,信号源+1

如何理解

举个现实中的例子(洗车),当有5个车主想要去洗车店洗车,但是这个洗车店的只有1个洗车位(相当于信号资源),那么只能先到先洗,等前一辆车洗完,后面的车才能洗,具体的用法是:dispatch_semaphore_create(1),洗车店有一个洗车位,当里面有车在洗车的时候dispatch_semaphore_wait(dispatch_semaphore_t dsema,dispatch_time_t timeout)信号资源-1等待前面的车洗好,假如前面的车洗好了,dispatch_semaphore_signal(dispatch_semaphore_t dsema),这个时候资源+1,后面的车就能洗,当后面的车在洗的时候dispatch_semaphore_wait,资源减1,如此按相对顺序5辆车一辆一辆洗完。

-(void)testDataErrorSetArray
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    NSMutableArray *mArray = [NSMutableArray array];
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);//洗车店只有一个洗车位
    for (int i = 0; i < 5; i++) {
        dispatch_async(queue, ^{
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//要洗车了信号资源-1
            [mArray addObject:[NSNumber numberWithInt:i]];//洗车中
            dispatch_semaphore_signal(semaphore);//洗完车发送信号+1
                   });
            }
}

另一个用法是AF中的一个函数,当请求回调block中不知道什么时候返回值,先创建一个资源为0的信号,然后一直等待的信号,当block中返回值成功后信号+1,继续执行下一步。

- (NSArray *)tasksForKeyPath:(NSString *)keyPath {
    __block NSArray *tasks = nil;
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
        if ([keyPath isEqualToString:NSStringFromSelector(@selector(dataTasks))]) {
            tasks = dataTasks;
        } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(uploadTasks))]) {
            tasks = uploadTasks;
        } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(downloadTasks))]) {
            tasks = downloadTasks;
        } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(tasks))]) {
            tasks = [@[dataTasks, uploadTasks, downloadTasks] valueForKeyPath:@"@unionOfArrays.self"];
        }

        dispatch_semaphore_signal(semaphore);
    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    return tasks;
}

相关文章

网友评论

      本文标题:关于GCD的dispatch_semaphore_t

      本文链接:https://www.haomeiwen.com/subject/mrjzxxtx.html