iOS多线程中的信号量

一、信号量锁定线程数量
例子:
在YYKit的源码中有信号量加锁的应用,

#define INIT(...) self = super.init; \
if (!self) return nil; \
__VA_ARGS__; \
if (!_dic) return nil; \
_lock = dispatch_semaphore_create(1); \
return self;


#define LOCK(...) dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); \
__VA_ARGS__; \
dispatch_semaphore_signal(_lock);

创建信号量值为1,当执行到dispatch_semaphore_wait()时,信号量变为0,可以执行下面代码VA_ARGS,如果在执行VA_ARGS中,有其他新城执行dispatch_semaphore_wait(),会被阻塞,直到VA_ARGS和dispatch_semaphore_signal()执行完。

从上面的可以看出,dispatch_semaphore_create(long value)中的value是最多几个线程访问共享资源,而一般value值为1。

二、信号量同步 异步的网络请求

NSString *appIdKey = @"xx";
NSString* urlString_1 = @"http://api.openweathermap.org/data/2.5/weather";
NSString* urlString_2 = @"http://api.openweathermap.org/data/2.5/forecast/daily";
NSDictionary* dictionary =@{@"lat":@"40.04991291",
                           @"lon":@"116.25626162",
                           @"APPID" : appIdKey};
// 创建组
dispatch_group_t group = dispatch_group_create();

// 将第一个网络请求任务添加到组中
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
   // 创建信号量为0的信号量,目的就是阻塞当前线程
   dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
   // 开始网络请求任务
   AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
   [manager GET:urlString_1 parameters:dictionary progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            // 如果请求成功,发送信号量
            dispatch_semaphore_signal(semaphore);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"失败请求数据");
            // 如果请求失败,也发送信号量
            dispatch_semaphore_signal(semaphore);
        }];
    // 在网络请求任务成功之前,次线程被阻塞,没有返回。
   dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // 创建信号量为0的信号量,目的就是阻塞当前线程
   dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
   // 开始网络请求任务
   AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
   [manager GET:urlString_2 parameters:dictionary progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

            // 如果请求成功,发送信号量
            dispatch_semaphore_signal(semaphore);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

            // 如果请求失败,也发送信号量
            dispatch_semaphore_signal(semaphore);
        }];
   // 在网络请求任务成功之前,次线程被阻塞,没有返回。
   dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});

dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
   NSLog(@"完成了网络请求,不管网络请求失败了还是成功了。");
});

这里较为特殊,创建信号量值为0,执行dispatch_semaphore_wait(),阻塞当前子线程,直到网络请求完成,当前子线程返回。这样多个请求都完成时,执行汇总操作。

你可能感兴趣的:(iOS多线程中的信号量)