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!