美文网首页iOS学习笔记2017-3-29
使用GCD中的dispatch_semaphore信号量(处理一

使用GCD中的dispatch_semaphore信号量(处理一

作者: 宋进锋 | 来源:发表于2017-12-14 17:18 被阅读15次

    1、什么是GCD的信号量?

    信号量:就是一种标识,简单来说就是控制访问资源的数量,比如系统有两个资源可以被利用,同时有三个线程要访问,只能允许两个线程访问,第三个应当等待资源被释放后再访问。

    注意:再GCD中,只有调度的线程在信号量不足的时候才会进入内核态进行线程阻塞。

    2、如何使用信号量

    三个主要函数

    ` dispatch_semaphore_t` :通俗的说我们可以理解成他是一个红绿灯的信号,当它的信号量为0时(红灯)等待,

    当信号量为1或大于1时(绿灯)走。

    // 创建一个信号,value:信号量

    dispatch_semaphore_create(<#long value#>)

    // 使某个信号的信号量+1

    dispatch_semaphore_signal(<#dispatch_semaphore_t dsema#>)

    // 某个信号进行等待, timeout:等待时间,永远等待为 DISPATCH_TIME_FOREVER

    dispatch_semaphore_wait(<#dispatch_semaphore_t dsema#>, <#dispatch_time_t timeout#>)

    创建一个信号量

    // 创建一个信号量为0的信号(红灯)

    dispatch_semaphore_t sema = dispatch_semaphore_create(0);

    // 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯)

    dispatch_semaphore_signal(sema);

    // 开启信号等待,设置等待时间为永久,直到信号的信号量大于等于1(绿灯)

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

    3、信号量的用法?

    问题1:

    开启两个主要异步线程,两个异步线程内部又得分别开启一个异步线程和其他耗时操作,最后还有第三个线程,这第三个线程必须等到前两个主要线程内部所有操作都完成以后再去执行,但是在执行以上这些操作的时候不能卡住界面。

    需求分析图如下:

    需求分析图

    实例:

    第一步:建立线程组

    dispatch_group_t group = dispatch_group_create();

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

    [self request1];

    NSLog(@"网络请求1");

    });

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

    [self request2];

    });

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{

    NSLog(@"刷新界面");

    [self request3];

    });

    第二步:建立网络请求

    1、网络请求1、网络请求2

    -(void)request1{

    //创建信号量并设置计数默认为0

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    manager.responseSerializer = [AFJSONResponseSerializer serializer];

    NSString *url = [NSString stringWithFormat:@"网络请求1"];

    [manager GET:url parameters:nil progress:^(NSProgress * _Nonnull uploadProgress) {

    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

    NSArray *data = responseObject[@"data"];

    for (NSDictionary *dic in data) {

    NSLog(@"请求1---%@",dic[@"id"]);

    }

    //计数加1

    dispatch_semaphore_signal(semaphore);

    //11380-- data.lastObject[@"id"];

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

    NSLog(@"shibai...");

    //计数加1

    dispatch_semaphore_signal(semaphore);

    }];

    //若计数为0则一直等待

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    }

    2、网络请求3

    -(void)request3{

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    manager.responseSerializer = [AFJSONResponseSerializer serializer];

    NSString *url2 = [NSString stringWithFormat:@"网络请求3"];

    [manager GET:url2 parameters:nil progress:^(NSProgress * _Nonnull uploadProgress) {

    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

    NSArray *data = responseObject[@"data"];

    for (NSDictionary *dic in data) {

    NSLog(@"请求3---%@",dic[@"id"]);

    }

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

    }];

    }

    相关文章

      网友评论

        本文标题:使用GCD中的dispatch_semaphore信号量(处理一

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