3种GCD线程同步方式分别是:
dispatch_semaphore_t
dispatch_barrier_async()
dispatch_group_notify()
第一种使用dispatch_semaphore_t实现线程同步
说明:block块异步任务添加到了全局并发队列里,主线程会跳过block块(同时开辟子线程异步执行block块)。
执行block块外的代码dispatch_semaphore_wait,因为semaphore信号量为0,且时间为DISPATCH_TIME_FOREVER,所以会阻塞当前线程(主线程),从而先执行子线程的block块,直到执行block块内部的dispatch_semaphore_signal使得信号量+1。正在被阻塞的线程(主线程)才恢复继续执行。这样保证了线程之间的同步。
- (void)test_dispatch_semaphore {
__block int j = 0;
// global全局并发队列
dispatch_queue_t queueu_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_semaphore_t semaphore_t = dispatch_semaphore_create(0);
dispatch_async(queueu_t, ^{
for (int i = 0; i < 1000; i++) {
j++;
}
dispatch_semaphore_signal(semaphore_t);
});
dispatch_semaphore_wait(semaphore_t, DISPATCH_TIME_FOREVER);
NSLog(@"j = %d", j);
}
2020-05-12 19:37:50.460186+0800 Test_Objective-C[3310:158423] j = 1000
第二种使用dispatch_barrier_async()
- (void)test_barrier_async {
// 新建并发队列
dispatch_queue_t queue_t_1 = dispatch_queue_create("com.queue_t_1", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue_t_1, ^{
NSLog(@"异步任务_1");
});
dispatch_async(queue_t_1, ^{
NSLog(@"异步任务_2");
});
dispatch_async(queue_t_1, ^{
NSLog(@"异步任务_3");
});
dispatch_barrier_sync(queue_t_1, ^{
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
NSLog(@"barrier执行任务,sum = %d", sum);
});
dispatch_async(queue_t_1, ^{
NSLog(@"异步任务_4");
});
}
2020-05-12 19:36:53.449664+0800 Test_Objective-C[3289:157683] 异步任务_1
2020-05-12 19:36:53.449696+0800 Test_Objective-C[3289:157686] 异步任务_3
2020-05-12 19:36:53.449715+0800 Test_Objective-C[3289:157684] 异步任务_2
2020-05-12 19:36:53.449996+0800 Test_Objective-C[3289:157602] barrier执行任务,sum = 4950
2020-05-12 19:36:53.450136+0800 Test_Objective-C[3289:157684] 异步任务_4
网友评论