5,dispatch_semaphore_t 控制并发线程数
有时在执行多任务时需要避免抢占资源以及性能过多消耗的情况,需要在特定时间内控制同时执行的任务数量,在NSOperationQueue可以通过maxConcurrentOperationCount来控制,在GCD中可以指定semaphore来控制了。先介绍3个函数,dispatch_semaphore_create创建一个semaphore;dispatch_semaphore_wait等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量-1;dispatch_semaphore_signal是发送一个信号,自然会让信号总量加1。看一个小例子:
- (void)test7 { _semaphore = dispatch_semaphore_create(2); [self task7_1]; [self task7_2]; [self task7_3]; [self task7_4]; } - (void)task7_1 { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER); NSLog(@"7_1_begin"); sleep(4); NSLog(@"7_1_end"); dispatch_semaphore_signal(_semaphore); }); } - (void)task7_2 { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER); NSLog(@"7_2_begin"); sleep(4); NSLog(@"7_2_end"); dispatch_semaphore_signal(_semaphore); }); } - (void)task7_3 { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER); NSLog(@"7_3_begin"); sleep(4); NSLog(@"7_3_end"); dispatch_semaphore_signal(_semaphore); }); } - (void)task7_4 { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER); NSLog(@"7_4_begin"); sleep(4); NSLog(@"7_4_end"); dispatch_semaphore_signal(_semaphore); }); } |
执行结果:
semaphore 为 1
2016-03-11 16:33:11.957 GCDSample[22394:2943718] 7_1_begin
2016-03-11 16:33:15.959 GCDSample[22394:2943718] 7_1_end
2016-03-11 16:33:15.960 GCDSample[22394:2943717] 7_2_begin
2016-03-11 16:33:19.964 GCDSample[22394:2943717] 7_2_end
2016-03-11 16:33:19.965 GCDSample[22394:2943721] 7_3_begin
2016-03-11 16:33:23.970 GCDSample[22394:2943721] 7_3_end
2016-03-11 16:33:23.970 GCDSample[22394:2943727] 7_4_begin
2016-03-11 16:33:27.975 GCDSample[22394:2943727] 7_4_end
------- ------- ------- ------- ------- ------- ------- ----
semaphore 为 2
2016-03-11 16:33:47.396 GCDSample[22406:2944975] 7_2_begin
2016-03-11 16:33:47.396 GCDSample[22406:2944974] 7_1_begin
2016-03-11 16:33:51.398 GCDSample[22406:2944975] 7_2_end
2016-03-11 16:33:51.398 GCDSample[22406:2944974] 7_1_end
2016-03-11 16:33:51.398 GCDSample[22406:2944976] 7_3_begin
2016-03-11 16:33:51.398 GCDSample[22406:2944983] 7_4_begin
2016-03-11 16:33:55.401 GCDSample[22406:2944976] 7_3_end
2016-03-11 16:33:55.401 GCDSample[22406:2944983] 7_4_end
可以看到,并发执行任务的数量取决于_semaphore = dispatch_semaphore_create(2);传入的数字,当为1时,效果如同执行串行队列。
6,dispatch_set_target_queue 设置队列优先级
如果有串行队列A和并行队列B,队列A中加入任务1,队列B中加入任务2、任务3,如果确保1、2、3顺序执行呢?可以通过dispatch_set_target_queue设置队列的优先级,将队列AB指派到队列C上,任务123将会在串行队列C中顺序执行。代码如下:
- (void)test8 { dispatch_queue_t serialQueue = dispatch_queue_create("com.starming.gcddemo.serialqueue", DISPATCH_QUEUE_SERIAL); dispatch_queue_t firstQueue = dispatch_queue_create("com.starming.gcddemo.firstqueue", DISPATCH_QUEUE_SERIAL); dispatch_queue_t secondQueue = dispatch_queue_create("com.starming.gcddemo.secondqueue", DISPATCH_QUEUE_CONCURRENT); dispatch_set_target_queue(firstQueue, serialQueue); dispatch_set_target_queue(secondQueue, serialQueue); dispatch_async(firstQueue, ^{ NSLog(@"1 %@",[NSThread currentThread]); [NSThread sleepForTimeInterval:3.f]; }); dispatch_async(secondQueue, ^{ NSLog(@"2 %@",[NSThread currentThread]); [NSThread sleepForTimeInterval:2.f]; }); dispatch_async(secondQueue, ^{ NSLog(@"3 %@",[NSThread currentThread]); [NSThread sleepForTimeInterval:1.f]; }); } |
执行结果:
2016-03-11 17:31:41.515 GCDSample[1202:730942] 1 <NSThread: 0x170078340>{number = 2, name = (null)}
2016-03-11 17:31:44.518 GCDSample[1202:730942] 2 <NSThread: 0x170078340>{number = 2, name = (null)}
2016-03-11 17:31:46.520 GCDSample[1202:730942] 3 <NSThread: 0x170078340>{number = 2, name = (null)}
未完待续,Have fun!