边开发边学习iOS项目实践中的学习

信号量的使用

2018-02-06  本文已影响14人  coderhlt

一、信号量的介绍

https://www.jianshu.com/p/24ffa819379c
https://www.jianshu.com/p/56c4838aa3e0

二、信号量的使用

#pragma mark - 网络请求一
- (void)getuserId:(dispatch_semaphore_t)semaphore{
   AFHTTPSessionManager *sessionmanger=[[AFHTTPSessionManager alloc]init];
   sessionmanger.responseSerializer=[AFHTTPResponseSerializer serializer];
   [sessionmanger POST:@"https://www.baidu.com/" parameters:nil constructingBodyWithBlock:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
         NSLog(@"请求成功1%@", [NSThread currentThread]);
        useid=@"1234";
       dispatch_semaphore_signal(semaphore);
   } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
       NSLog(@"%@",error);
        dispatch_semaphore_signal(semaphore);
   }];
   
}

#pragma mark - 网络请求二
- (void)requestwithuserid:(NSString *)userid{
   NSDictionary *parms=[NSMutableDictionary dictionary];
   [parms setValue:userid forKey:@"userid"];
   AFHTTPSessionManager *sessionmanger=[[AFHTTPSessionManager alloc]init];
   sessionmanger.responseSerializer=[AFHTTPResponseSerializer serializer];
   [sessionmanger POST:@"https://www.baidu.com/" parameters:userid constructingBodyWithBlock:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
       NSLog(@"请求成功2");
   } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
       NSLog(@"%@",error);
   }];
}

#pragma mark - 使用信号量实现
- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_semaphore_t semaphore= dispatch_semaphore_create(0); // 创建信号量
    [self getuserId:semaphore];//获取用户useid
 
dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);//当前信号量为0,一直等待阻塞线程
    [self requestwithuserid:useid];
}

command+R运行一下,没有任何反应。
原因分析:线程卡住了。代码执行到dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER)因为信号量为0,当前线程会被阻塞。而当前线程是主线程,网络请求一成功后回调到主线程,因为主线程被阻塞 造成信号量无法释放,一直卡住。
解决方案就是开启一个异步的线程

- (void)viewDidLoad {
    [super viewDidLoad];
    //创建一个并行队列
    dispatch_queue_t queque = dispatch_queue_create("GoyakodCreated", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queque, ^{
        dispatch_semaphore_t semaphore= dispatch_semaphore_create(0); // 创建信号量
        [self getuserId:semaphore];
        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
        [self requestwithuserid:useid];
    });
}
    dispatch_queue_t queque = dispatch_queue_create("GoyakodCreated", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queque, ^{
        for (NSInteger i=0;i<imageArray.count;i++) {
            dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
            [[AFHttpRequest shareRequest]  unifiedPicConversionWithchannelNo:@"" businessNum:@"" serialNum:serialNum sendType:@"" picName:picName picDirection:@"" picIoStr:picBase64Str serverSuccessFn:^(id dict) {
                dispatch_semaphore_signal(semaphore);
            } serverFailureFn:^(NSError *error) {
                dispatch_semaphore_signal(semaphore);
      
            }];
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        }
    });
//定义一个信号量,初始化为10
dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
    
//同时执行100个任务
 for (int i = 0; i < 100; i++)
 {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
    //当前信号量-1
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            
    NSLog(@"任务%d执行",i+1);
            
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kUrlString]];

    dispatch_async(dispatch_get_main_queue(), ^{
        //TODO:刷新界面
    });
            
    //当前信号量+1
    dispatch_semaphore_signal(semaphore);
            
    });
}

开始初始化一个信号量,默认为10,然后同时执行100个任务,所以每次最大并发是10。dispatch_semaphore_wait表示是当前的信号量减去1,因为已经启动一个任务,所以通过这个方法来修改信号量的值。同样,当当前任务执行完后,要释放信号量,使当前信号量加1,所以用dispatch_semaphore_signal方法

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    dispatch_group_t group = dispatch_group_create();
    // 创建信号量
   semaphore = dispatch_semaphore_create(0);
    // 创建全局并行
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_group_async(group, queue, ^{

        [self request1];

    });
    
    dispatch_group_async(group, queue, ^{
       
        [self request2];
 
    });
    
    dispatch_group_notify(group, queue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        //在这里 进行请求后的方法,回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            
            NSLog(@"更新UI");
            
        });
    });
    NSLog(@"12344");
    
}
- (void)request1{
    AFHTTPSessionManager *manger=[[AFHTTPSessionManager alloc]init];
    manger.responseSerializer=[AFHTTPResponseSerializer serializer];
    [manger POST:@"https://www.baidu.com" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"请求成功1");
        dispatch_semaphore_signal(semaphore);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
         dispatch_semaphore_signal(semaphore);
    }];

}
- (void)request2{
    AFHTTPSessionManager *manger=[[AFHTTPSessionManager alloc]init];
    manger.responseSerializer=[AFHTTPResponseSerializer serializer];
    [manger POST:@"https://www.baidu.com" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"请求成功2");
        dispatch_semaphore_signal(semaphore);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
         dispatch_semaphore_signal(semaphore);
    }];
   
}

或者这样

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    dispatch_group_t group = dispatch_group_create();
   
    // 创建全局并行
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_group_async(group, queue, ^{

        [self request1];

    });
    
    dispatch_group_async(group, queue, ^{
       
        [self request2];
 
    });
    
    dispatch_group_notify(group, queue, ^{

        //在这里 进行请求后的方法,回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            
            NSLog(@"更新UI");
            
        });
    });
    NSLog(@"12344");
    
}
- (void)request1{
    // 创建信号量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    AFHTTPSessionManager *manger=[[AFHTTPSessionManager alloc]init];
    manger.responseSerializer=[AFHTTPResponseSerializer serializer];
    [manger POST:@"https://www.baidu.com" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"请求成功1");
         NSLog(@"%ld", dispatch_semaphore_signal(semaphore));
       ;
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
         dispatch_semaphore_signal(semaphore);
        NSLog(@"%@",semaphore);
    }];
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
- (void)request2{
    // 创建信号量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    AFHTTPSessionManager *manger=[[AFHTTPSessionManager alloc]init];
    manger.responseSerializer=[AFHTTPResponseSerializer serializer];
    [manger POST:@"https://www.baidu.com" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"请求成功2");
        dispatch_semaphore_signal(semaphore);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
         dispatch_semaphore_signal(semaphore);
    }];
     dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
@end
上一篇下一篇

猜你喜欢

热点阅读