遇到的问题
多线程异步并行会导致多个线程的顺序随机执行
信号量(Semaphore)
可以控制线程并发的数量,且可以通过信号量来控制信号量执行顺序.
1.创建信号量,参数为初始值
dispatch_semaphore_create(信号量值)
2.等待降低信号量,等待资源使用权
dispatch_semaphore_wait(信号量,等待时间)
3.提高信号量,释放资源使用权
dispatch_semaphore_signal(信号量)
注意:
dispatch_semaphore_signal与dispatch_semaphore_wait一般为配对使用
signal升高信号量+1,wait降低信号量-1
当信号量为0时再执行wait会导致信号量小于0,阻塞线程
未使用信号量时
/**
2021-07-21 20:36:03.756500+0800 SemaDemo[1331:20883] run task2
2021-07-21 20:36:03.756510+0800 SemaDemo[1331:20881] run task3
2021-07-21 20:36:03.756518+0800 SemaDemo[1331:20882] run task4
2021-07-21 20:36:03.756500+0800 SemaDemo[1331:20885] run task1
顺序随机
*/
- (void)normalThread{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSLog(@"run task1");
});
dispatch_async(queue, ^{
NSLog(@"run task2");
});
dispatch_async(queue, ^{
NSLog(@"run task3");
});
dispatch_async(queue, ^{
NSLog(@"run task4");
});
}
与queue结合可以完成多个接口顺序完成需求.
/**
2021-07-22 12:58:41.810017+0800 SemaDemo[1978:31675] run task1
2021-07-22 12:58:41.810205+0800 SemaDemo[1978:31675] run task2
2021-07-22 12:58:41.810353+0800 SemaDemo[1978:31675] run task3
2021-07-22 12:58:41.810494+0800 SemaDemo[1978:31675] run task4
顺序执行
*/
- (void)semaphoreThread_0{
//信号量初始值为0
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSLog(@"run task1");
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(queue, ^{
NSLog(@"run task2");
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(queue, ^{
NSLog(@"run task3");
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(queue, ^{
NSLog(@"run task4");
dispatch_semaphore_signal(semaphore);
});
}
与group,queue结合可以完成多个接口操作完,进行下一步操作的需求.
/**
2021-07-23 15:28:32.030550+0800 SemaDemo[22090:312053] 2请求成功
2021-07-23 15:28:32.095009+0800 SemaDemo[22090:312050] 1请求成功
2021-07-23 15:28:32.095012+0800 SemaDemo[22090:312048] 信号量为0
2021-07-23 15:28:32.116285+0800 SemaDemo[22090:312053] 3请求成功
或
2021-07-23 15:28:32.030550+0800 SemaDemo[22090:312053] 1请求成功
2021-07-23 15:28:32.095009+0800 SemaDemo[22090:312050] 2请求成功
2021-07-23 15:28:32.095012+0800 SemaDemo[22090:312048] 信号量为0
2021-07-23 15:28:32.116285+0800 SemaDemo[22090:312053] 3请求成功
*/
- (void)groupThread{
//结束请求进行下一步操作,不注重顺序
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSURLSessionDataTask * dataTask = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_semaphore_signal(semaphore);
NSLog(@"1请求成功");
}];
[dataTask resume];
});
dispatch_group_async(group, queue, ^{
NSURLSessionDataTask * dataTask = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_semaphore_signal(semaphore);
NSLog(@"2请求成功");
}];
[dataTask resume];
});
dispatch_group_notify(group, queue, ^{
// 信号量为0时再wait会阻塞线程
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"信号量为0");
NSURLSessionDataTask * dataTask = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_semaphore_signal(semaphore);
NSLog(@"3请求成功");
}];
[dataTask resume];
});
}