信号量的锁如果多释放信号会怎么样
dispatch_semaphore_t lock = dispatch_semaphore_create(1); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"任务1"); dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER); NSLog(@"任务1 over"); dispatch_semaphore_signal(lock); NSLog(@"任务1 ----->1"); dispatch_semaphore_signal(lock); NSLog(@"任务1 ----->2"); dispatch_semaphore_signal(lock); NSLog(@"任务1 ----->3"); }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"任务2"); dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER); NSLog(@"任务2 over"); }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"任务3"); dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER); NSLog(@"任务3 over"); }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"任务4"); dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER); NSLog(@"任务4 over"); });
2020-09-10 19:18:26.347357+0800 FindClassMethods[6856:271676] 任务1 2020-09-10 19:18:26.347364+0800 FindClassMethods[6856:271671] 任务2 2020-09-10 19:18:26.347387+0800 FindClassMethods[6856:271675] 任务3 2020-09-10 19:18:26.347400+0800 FindClassMethods[6856:271672] 任务4 2020-09-10 19:18:26.347539+0800 FindClassMethods[6856:271676] 任务1 over 2020-09-10 19:18:26.347656+0800 FindClassMethods[6856:271676] 任务1 ----->1 2020-09-10 19:18:26.347667+0800 FindClassMethods[6856:271671] 任务2 over 2020-09-10 19:18:26.347743+0800 FindClassMethods[6856:271676] 任务1 ----->2 2020-09-10 19:18:26.347755+0800 FindClassMethods[6856:271675] 任务3 over 2020-09-10 19:18:26.347995+0800 FindClassMethods[6856:271676] 任务1 ----->3 2020-09-10 19:18:26.348008+0800 FindClassMethods[6856:271672] 任务4 over
如上所示,如果运气好第一个先执行,那么就会出现1得到锁,2,3,4必须等待,1执行任务,1放开一个锁,另一个线程2立即得到锁,2执行任务,1继续放开一个锁,然后被3得到了... (所以唤起另一个线程之后会立即执行这个线程?)
如果说,一开始先执行了多次释放信号量,后面加锁但是没有释放信号量也可以有多个线程得到锁往下执行,说明每释放一次就会+1信号量,多释放可能会出现自己不希望的结果,所以对信号量值的掌握要相当有把握才行
dispatch_semaphore_t lock = dispatch_semaphore_create(1); // dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"任务1"); NSLog(@"任务1 %ld",dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)); NSLog(@"任务1 over"); NSLog(@"任务1 ----->%ld",dispatch_semaphore_signal(lock)); NSLog(@"任务1 ----->%ld",dispatch_semaphore_signal(lock)); NSLog(@"任务1 ----->%ld",dispatch_semaphore_signal(lock)); // }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"任务2"); NSLog(@"任务2 %ld",dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)); NSLog(@"任务2 over"); }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"任务3"); NSLog(@"任务3 %ld",dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)); NSLog(@"任务3 over"); }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"任务4"); NSLog(@"任务4 %ld",dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)); NSLog(@"任务4 over"); NSLog(@"任务4 ----->%ld",dispatch_semaphore_signal(lock)); }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"任务5"); NSLog(@"任务5 %ld",dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)); NSLog(@"任务5 over"); }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"任务6"); NSLog(@"任务6 %ld",dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)); NSLog(@"任务6 over"); });
2020-09-10 19:31:07.739063+0800 FindClassMethods[6937:278894] 任务1 2020-09-10 19:31:07.739182+0800 FindClassMethods[6937:278894] 任务1 0 2020-09-10 19:31:07.739307+0800 FindClassMethods[6937:278894] 任务1 over 2020-09-10 19:31:07.739441+0800 FindClassMethods[6937:278894] 任务1 ----->0 2020-09-10 19:31:07.739518+0800 FindClassMethods[6937:278894] 任务1 ----->0 2020-09-10 19:31:07.739604+0800 FindClassMethods[6937:278894] 任务1 ----->0 2020-09-10 19:31:07.739742+0800 FindClassMethods[6937:278954] 任务2 2020-09-10 19:31:07.739751+0800 FindClassMethods[6937:278950] 任务3 2020-09-10 19:31:07.739763+0800 FindClassMethods[6937:278952] 任务4 2020-09-10 19:31:07.739772+0800 FindClassMethods[6937:278951] 任务6 2020-09-10 19:31:07.739779+0800 FindClassMethods[6937:278953] 任务5 2020-09-10 19:31:07.739836+0800 FindClassMethods[6937:278954] 任务2 0 2020-09-10 19:31:07.739856+0800 FindClassMethods[6937:278950] 任务3 0 2020-09-10 19:31:07.739863+0800 FindClassMethods[6937:278952] 任务4 0 2020-09-10 19:31:07.740217+0800 FindClassMethods[6937:278954] 任务2 over 2020-09-10 19:31:07.740366+0800 FindClassMethods[6937:278952] 任务4 over 2020-09-10 19:31:07.740689+0800 FindClassMethods[6937:278952] 任务4 ----->1 2020-09-10 19:31:07.740695+0800 FindClassMethods[6937:278951] 任务6 0 2020-09-10 19:31:07.740813+0800 FindClassMethods[6937:278950] 任务3 over 2020-09-10 19:31:07.742692+0800 FindClassMethods[6937:278951] 任务6 over
dispatch_semaphore_wait返回0标识获得锁成功,往下执行,否则等待超时失败。
dispatch_semaphore_signal返回0标识当前没有等待的线程,否则标识跳转到其他线程执行任务