- GCD 中的信号量是指 Dispatch Semaphore,是持有计数的信号。类似于过高速路收费站的栏杆。可以通过时,打开栏杆,不可以通过时,关闭栏杆。
- 在 Dispatch Semaphore中,使用计数来完成这个功能,计数为0时等待,不可通过。计数为1或大于1时,计数减1且不等待,可通过。
- Dispatch Semaphore提供了三个函数:
- dispatch_semaphore_create:创建一个Semaphore并初始化信号的总量
- dispatch_semaphore_signal:发送一个信号,让信号总量加1
- dispatch_semaphore_wait:可以使总信号量减1,当信号总量为0时就会一直等待(阻塞所在线程),否则就可以正常执行。
#pragma mark dispatch_semaphore信号量
- (void)gcd_dispatch_semaphore {
//打印当前线程
NSLog(@"currentThread---%@",[NSThread currentThread]);
NSLog(@"semaphore---begin");
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block NSInteger number = 0;
dispatch_async(queue, ^{
// 追加任务1
//模拟耗时操作
[NSThread sleepForTimeInterval:2];
//打印当前线程
NSLog(@"1---%@",[NSThread currentThread]);
number = 100;
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"semaphore---end,number = %ld",(long)number);
}
输出结果:
2020-07-06 15:28:49.979677+0800 GCD[2989:1190741] currentThread---<NSThread: 0x2804b4f80>{number = 1, name = main}
2020-07-06 15:28:49.979764+0800 GCD[2989:1190741] semaphore---begin
2020-07-06 15:28:51.984955+0800 GCD[2989:1190767] 1---<NSThread: 0x28048f400>{number = 3, name = (null)}
2020-07-06 15:28:51.985111+0800 GCD[2989:1190741] semaphore---end,number = 100
- semaphore---end是在执行完 number = 100;之后才打印的,而且输出结果 number 为 100。
- 这是因为异步执行不会做任何等待,可以继续执行任务。
- 异步执行将任务1追加到队列之后,不做等待,接着执行dispatch_semaphore_wait方法。
- 此时 semaphore == 0,当前线程进入等待状态。然后,异步任务1开始执行。
- 任务1执行到dispatch_semaphore_signal之后,总信号量,此时 semaphore == 1,dispatch_semaphore_wait方法使总信号量减1,正在被阻塞的线程(主线程)恢复继续执行。
- 最后打印semaphore---end,number = 100。
- 这样就实现了线程同步,将异步执行任务转换为同步执行任务。
网友评论