项目中用到了阿里云上传,有20张图片加3个音频加视频文件,用到了GCD的东西,总结了一下。
代码地址:https://github.com/SunshineTraveller/LMGCDTEST
凌晨五点了 直接上代码吧还是 有注释
总结:
// GCD 总结 /
一、同步:1.1不区分串行或并发,和队列创建数目无关,都是在一个线程中执行。测试中任务在主线程中进行,会阻塞线程
二、异步:2.1区分串行和并发
2.1.1 串行:一个队列只会创建一个子线程,线程中的任务会按顺序依次执行,任务之间是有等待的,后面的任务会等前面的任务完成后再去执行,不会阻塞线程
多个队列会创建多个子线程,每个线程的任务相对无序执行,任务之间没有等待,所有任务之间没有相互约束
2.1.2 并发:和队列数无关,n个任务会创建n个子线程,所有任务之间没有等待,不存在相互约束
三、组: group里的任务会在执行完后通过后通过通知回调(区分同步任务和异步任务!)
3.1 group里执行的是同步任务(sync)
dispatch_group_async(dispatch_group_t group,dispatch_queue_t queue,dispatch_block_t block);异步组函数里面的queue不能是串行队列类型(DISPATCH_QUEUE_SERIAL),否则不会执行,需为并发或者全局队列
3.1.1 特点:group组会在放入group的队列里执行的任务会在全部任务执行完毕后通过dispatch_group_notify回调,告知外界group里的任务已经全部执行完毕,然后才会执行其他任务,group的队列会根据任务数创建对应的线程数,n个任务就会有n个线程,并且是按顺序执行的
3.2 group里执行的是异步任务(async)
!此时需要注意了,若为异步任务,若不做任何处理,所有任务的执行和通知会同时执行,需要添加 enter和 leave!这样才能达到group里的任务都执行完毕才会通知,然后执行其他任务
四、 barrier:就像屏障一样,隔开屏障前后的任务
4.1 dispatch_barrier_async 同步若同步执行队列,任务有序执行,且barrier后面的任务会在barrier前的任务执行完后才会去执行
4.2 dispatch_barrier_sync 异步若异步执行队列,任务无序执行,会开启新线程且任务数多于线程数,barrier后面的任务会在barrier里的任务执行完后才会去执行
五、信号量 semaphore:记住一点即可!当信号总量 <0的时候,它的wait方法便会暂停,直到信号总量 >= 0的时候才会执行wait下面的方法,信号量增加的方法就是signal那个方法!
dispatch_semaphore_wait:英文注释:Decrement the counting semaphore. If the resulting value is less than zero,this function waits for a signal to occur before returning.
大致翻译:减掉信号量的总数,若减去后的结果值小于0,则该函数在返回之前会等待一个信号发送
keypoint: 1. dispatch_semaphore_wait函数会在信号量总数小于0的时候开始等待(tip:大于0则不会等待),wait后的所有任务都不会执行,直到信号量总数大于0。可以通过 dispatch_semaphore_signal 发送信号来增加信号量总数,一旦信号量总数大于0,wait函数就会结束等待,后面的任务就会开始执行
//
/**
* 同步串行和队列数无关,不会开启新线程,会阻塞当前线程
* 本次测试在主线程中
*/
- (IBAction)syncSerial:(id)sender {
dispatch_queue_t sync_serial_queue =dispatch_queue_create("sync_serial_queue",DISPATCH_QUEUE_SERIAL);
dispatch_queue_t sync_serial_queue2 =dispatch_queue_create("sync_serial_queue2",DISPATCH_QUEUE_SERIAL);
dispatch_queue_t sync_serial_queue3 =dispatch_queue_create("sync_serial_queue3",DISPATCH_QUEUE_SERIAL);
dispatch_sync(sync_serial_queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"syncSerial 1: *** %@",[NSThreadcurrentThread]);
});
dispatch_sync(sync_serial_queue2, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"syncSerial 2: *** %@",[NSThreadcurrentThread]);
});
dispatch_sync(sync_serial_queue3, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"syncSerial 3: *** %@",[NSThreadcurrentThread]);
});
NSLog(@"syncSerial测试 ");
}
控制台:
2017-09-22 05:15:12.047 LMGCDTest[4937:384806] syncSerial 1: *** <NSThread: 0x174265580>{number = 1, name = main}
2017-09-22 05:15:15.049 LMGCDTest[4937:384806] syncSerial 2: *** <NSThread: 0x174265580>{number = 1, name = main}
2017-09-22 05:15:18.051 LMGCDTest[4937:384806] syncSerial 3: *** <NSThread: 0x174265580>{number = 1, name = main}
2017-09-22 05:15:18.052 LMGCDTest[4937:384806] syncSerial 测试
/**
* 同步并发不会开启新线程,会阻塞当前线程,任务不会同时开始
*/
- (IBAction)syncConcurrent:(id)sender {
dispatch_queue_t sync_concurrent =dispatch_queue_create("sync_concurrent",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t sync_concurrent2 =dispatch_queue_create("sync_concurrent2",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t sync_concurrent3 =dispatch_queue_create("sync_concurrent3",DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(sync_concurrent, ^{
NSLog(@"sync_concurrent 1: *** %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
dispatch_sync(sync_concurrent2, ^{
NSLog(@"sync_concurrent 2: *** %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
dispatch_sync(sync_concurrent3, ^{
NSLog(@"sync_concurrent 3: *** %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
NSLog(@"sync_concurrent测试 ");
}
控制台:
2017-09-22 05:15:53.169 LMGCDTest[4954:385224] sync_concurrent 1: *** <NSThread: 0x17407d800>{number = 1, name = main}
2017-09-22 05:15:56.171 LMGCDTest[4954:385224] sync_concurrent 2: *** <NSThread: 0x17407d800>{number = 1, name = main}
2017-09-22 05:15:59.173 LMGCDTest[4954:385224] sync_concurrent 3: *** <NSThread: 0x17407d800>{number = 1, name = main}
2017-09-22 05:16:02.175 LMGCDTest[4954:385224] sync_concurrent测试
/**
* 异步串行一个队列只会创建一个线程,队列里的任务会按顺序执行(串行),不会阻塞线程
* 异步串行 n个队列创建n个线程,各队列里的任务并发无序执行,不会阻塞线程
*/
- (IBAction)asyncSerial:(id)sender {
dispatch_queue_t async_Serial =dispatch_queue_create("async_Serial",DISPATCH_QUEUE_SERIAL);
dispatch_queue_t async_Serial2 =dispatch_queue_create("async_Serial2",DISPATCH_QUEUE_SERIAL);
dispatch_queue_t async_Serial3 =dispatch_queue_create("async_Serial3",DISPATCH_QUEUE_SERIAL);
dispatch_async(async_Serial, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"async_concurrent 1: *** %@",[NSThreadcurrentThread]);
});
dispatch_async(async_Serial2, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"async_concurrent 2: *** %@",[NSThreadcurrentThread]);
});
dispatch_async(async_Serial3, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"async_concurrent 3: *** %@",[NSThreadcurrentThread]);
});
NSLog(@"async_Serial测试 ");
}
控制台:
2017-09-22 05:17:22.529 LMGCDTest[4968:385500] async_Serial测试
2017-09-22 05:17:25.531 LMGCDTest[4968:385714] async_concurrent 2: *** <NSThread: 0x1702662c0>{number = 3, name = (null)}
2017-09-22 05:17:25.531 LMGCDTest[4968:385712] async_concurrent 1: *** <NSThread: 0x174274a80>{number = 2, name = (null)}
2017-09-22 05:17:25.532 LMGCDTest[4968:385713] async_concurrent 3: *** <NSThread: 0x170266dc0>{number = 4, name = (null)}
/**
* 异步并发
* 和队列数无关,n个任务会创建n个线程,任务无序并发执行,不阻塞当前线程
*/
- (IBAction)asyncConcurrent:(id)sender {
dispatch_queue_t asyncConcurrent =dispatch_queue_create("asyncConcurrent",DISPATCH_QUEUE_CONCURRENT);
dispatch_async(asyncConcurrent, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"asyncConcurrent 1: *** %@",[NSThreadcurrentThread]);
});
dispatch_async(asyncConcurrent, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"asyncConcurrent 2: *** %@",[NSThreadcurrentThread]);
});
dispatch_async(asyncConcurrent, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"asyncConcurrent 3: *** %@",[NSThreadcurrentThread]);
});
NSLog(@"asyncConcurrent测试 ");
}
控制台:
2017-09-22 05:17:42.997 LMGCDTest[4968:385500] asyncConcurrent测试
2017-09-22 05:17:46.003 LMGCDTest[4968:385754] asyncConcurrent 2: *** <NSThread: 0x17426d2c0>{number = 6, name = (null)}
2017-09-22 05:17:46.003 LMGCDTest[4968:385753] asyncConcurrent 1: *** <NSThread: 0x17026e900>{number = 5, name = (null)}
2017-09-22 05:17:46.005 LMGCDTest[4968:385755] asyncConcurrent 3: *** <NSThread: 0x17426f200>{number = 7, name = (null)}
/*
* group里执行的是同步任务,并发按次序执行任务,每个任务都会在新线程中执行
* group里的任务完成后会回调通知
**/
- (IBAction)group:(id)sender {
/* 1. group里执行的是同步任务 */
// dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// dispatch_queue_t queue = dispatch_queue_create("sieral_queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue =dispatch_queue_create("sieral_queue",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue1 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_t group_t =dispatch_group_create();
// 放在组中组中执行的都是同步任务
dispatch_group_async(group_t, queue, ^{
dispatch_sync(queue, ^{
NSLog(@"group_sync task 1: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
});
dispatch_group_async(group_t, queue, ^{
dispatch_sync(queue, ^{
NSLog(@"group_sync task 2: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
});
dispatch_group_async(group_t, queue, ^{
dispatch_sync(queue, ^{
NSLog(@"group_sync task 3: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
});
// 前三个任务完成后再去执行其他任务
dispatch_group_notify(group_t, queue1, ^{
NSLog(@"前三个同步任务执行完毕收到通知,执行第四个,group_task 4: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
NSLog(@"group sync Test");
}
控制台:
2017-09-22 05:18:06.217 LMGCDTest[4968:385500] group sync Test
2017-09-22 05:18:06.219 LMGCDTest[4968:385773] group_sync task 1: <NSThread: 0x174269640>{number = 8, name = (null)}
2017-09-22 05:18:06.220 LMGCDTest[4968:385786] group_sync task 2: <NSThread: 0x170276d40>{number = 9, name = (null)}
2017-09-22 05:18:06.221 LMGCDTest[4968:385787] group_sync task 3: <NSThread: 0x17026a340>{number = 10, name = (null)}
2017-09-22 05:18:09.227 LMGCDTest[4968:385787] 前三个同步任务执行完毕收到通知,执行第四个,group_task 4: <NSThread: 0x17026a340>{number = 10, name = (null)}
/**
* group里执行的是异步任务,此时需要加 ‘进入enter’和‘离开leave’组,否则通知回调会立即执行
* 任务执行时enter 任务完成后leave
* 若任务结束时不在当前方法内,设置group为全局变量即可
*/
- (IBAction)group_async:(id)sender {
/** 2.group中执行的是异步任务,需要引入entre和leave */
dispatch_group_t group_t2 =dispatch_group_create();
dispatch_queue_t queue_t2 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_queue_t queue_t2_1 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
// 进入group_t2组(进入组和离开组必须成对出现,否则会造成死锁)
dispatch_group_enter(group_t2);
// 组里的任务都是异步任务
dispatch_group_async(group_t2, queue_t2, ^{
dispatch_async(queue_t2, ^{
NSLog(@"group_async Task1: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
// 离开
dispatch_group_leave(group_t2);
});
});
dispatch_group_enter(group_t2);
dispatch_group_async(group_t2, queue_t2, ^{
dispatch_async(queue_t2, ^{
NSLog(@"group_async Task2: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
// 离开
dispatch_group_leave(group_t2);
});
});
dispatch_group_enter(group_t2);
dispatch_group_async(group_t2, queue_t2, ^{
dispatch_async(queue_t2, ^{
NSLog(@"group_async Task3: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
// 离开
dispatch_group_leave(group_t2);
});
});
// 组里的任务完成后通知
dispatch_group_notify(group_t2, queue_t2_1, ^{
NSLog(@"group_async Task4: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
NSLog(@"group asycn Test");
}
控制台:
2017-09-22 05:18:33.905 LMGCDTest[4968:385500] group asycn Test
2017-09-22 05:18:33.906 LMGCDTest[4968:385834] group_async Task1: <NSThread: 0x17026e900>{number = 11, name = (null)}
2017-09-22 05:18:33.907 LMGCDTest[4968:385835] group_async Task2: <NSThread: 0x174274340>{number = 12, name = (null)}
2017-09-22 05:18:33.908 LMGCDTest[4968:385836] group_async Task3: <NSThread: 0x174263c80>{number = 13, name = (null)}
2017-09-22 05:18:36.913 LMGCDTest[4968:385836] group_async Task4: <NSThread: 0x174263c80>{number = 13, name = (null)}
/**
* barrier 同步
* 1.串行队列 任务在主线程中按序执行,会阻塞线程,barrier后的任务在barrier执行完后按序执行
* 2.并发队列 任务在主线程中按序执行,会阻塞线程,barrier后的任务在barrier执行完后按序执行
*/
- (IBAction)sync_barrier:(id)sender {
// dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue =dispatch_queue_create("queue",DISPATCH_QUEUE_CONCURRENT);
// 先执行的任务
dispatch_sync(queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"sync_barrier Task1: %@",[NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"sync_barrier Task2: %@",[NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"sync_barrier Task3: %@",[NSThreadcurrentThread]);
});
// 使用barrier阻断后面任务的执行
dispatch_barrier_sync(queue, ^{
NSLog(@"sync_barrier Task4: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
// 后执行的任务
dispatch_sync(queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"sync_barrier Task5: %@",[NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"sync_barrier Task6: %@",[NSThreadcurrentThread]);
});
NSLog(@"sync_barrier Test");
}
控制台:
2017-09-22 05:19:05.977 LMGCDTest[4968:385500] sync_barrier Task1: <NSThread: 0x174263d00>{number = 1, name = main}
2017-09-22 05:19:08.979 LMGCDTest[4968:385500] sync_barrier Task2: <NSThread: 0x174263d00>{number = 1, name = main}
2017-09-22 05:19:11.981 LMGCDTest[4968:385500] sync_barrier Task3: <NSThread: 0x174263d00>{number = 1, name = main}
2017-09-22 05:19:11.982 LMGCDTest[4968:385500] sync_barrier Task4: <NSThread: 0x174263d00>{number = 1, name = main}
2017-09-22 05:19:17.984 LMGCDTest[4968:385500] sync_barrier Task5: <NSThread: 0x174263d00>{number = 1, name = main}
2017-09-22 05:19:20.987 LMGCDTest[4968:385500] sync_barrier Task6: <NSThread: 0x174263d00>{number = 1, name = main}
2017-09-22 05:19:20.987 LMGCDTest[4968:385500] sync_barrier Test
/**
* barrier 异步
* 串行队列下,会创建子线程,任务按序执行,在barrier执行后才会执行之后的任务
* 并行队列下,会创建子线程,barrier之前的任务并发无序执行,barrier后的任务无序并发执行
*/
- (IBAction)async_barrier:(id)sender {
// dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
// dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue =dispatch_queue_create("queue",DISPATCH_QUEUE_CONCURRENT);
// 先执行的任务
dispatch_async(queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"async_barrier Task1: %@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"async_barrier Task2: %@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"async_barrier Task3: %@",[NSThreadcurrentThread]);
});
// 使用barrier阻断
dispatch_barrier_async(queue, ^{
NSLog(@"async_barrier Task4: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
// 后执行的任务
dispatch_async(queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"async_barrier Task5: %@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"async_barrier Task6: %@",[NSThreadcurrentThread]);
});
NSLog(@"async_barrier Test ");
}
控制台:
2017-09-22 05:19:46.713 LMGCDTest[4968:385500] async_barrier Test
2017-09-22 05:19:49.717 LMGCDTest[4968:385944] async_barrier Task1: <NSThread: 0x170263100>{number = 14, name = (null)}
2017-09-22 05:19:49.719 LMGCDTest[4968:385945] async_barrier Task2: <NSThread: 0x17026b800>{number = 15, name = (null)}
2017-09-22 05:19:49.719 LMGCDTest[4968:385946] async_barrier Task3: <NSThread: 0x174269dc0>{number = 16, name = (null)}
2017-09-22 05:19:49.720 LMGCDTest[4968:385946] async_barrier Task4: <NSThread: 0x174269dc0>{number = 16, name = (null)}
2017-09-22 05:19:55.731 LMGCDTest[4968:385945] async_barrier Task6: <NSThread: 0x17026b800>{number = 15, name = (null)}
2017-09-22 05:19:55.731 LMGCDTest[4968:385946] async_barrier Task5: <NSThread: 0x174269dc0>{number = 16, name = (null)}
/**
* 信号量
* dispatch_semaphore_wait:Decrement the counting semaphore. If the resulting value is less than zero,this function waits for a signal to occur before returning.
* wait函数:减掉信号量的总数,若减去后的结果值小于0,则该函数在返回之前会等待一个信号发送
*
* keypoint: 1. dispatch_semaphore_wait函数会在信号量总数小于0的时候开始等待(tip:大于0则不会等待),wait后的所有任务都不会执行,直到信号量总数大于0。可以通过 dispatch_semaphore_signal 发送信号来增加信号量总数,一旦信号量总数大于0,wait函数就会结束等待,后面的任务就会开始执行
*/
- (IBAction)semaphore:(id)sender {
dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_async(queue, ^{
// task1
NSLog(@"task1 : %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
NSLog(@"task1.1 : %@",[NSThreadcurrentThread]);
});
// 信号量创建
dispatch_semaphore_t sema =dispatch_semaphore_create(0);
NSLog(@"等待前 %@",sema);
dispatch_async(queue, ^{
// task2
[NSThreadsleepForTimeInterval:10];
NSLog(@"task2: %@",[NSThreadcurrentThread]);
NSLog(@"发信号 %@",sema);
dispatch_semaphore_signal(sema);
});
// 等待
dispatch_semaphore_wait(sema,DISPATCH_TIME_FOREVER);
// 结束
NSLog(@"等待后 %@",sema);
dispatch_async(queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"task3: %@",[NSThreadcurrentThread]);
});
/*
代码说明:
代码一开始会创建总数为0的信号量,同时异步执行queue里的任务task1和task2,接着执行dispatch_semaphore_wait函数,wait函数会使信号量-1,变成-1,由于-1<0 , wait函数开始等待,当然wait后面的代码是不会执行的。3秒后,task1任务执行完毕;task2里的任务会等10秒,然后执行dispatch_semaphore_signal发送了一个信号,signal会使信号量+1,这时信号量变成了0,wait函数在监听到信号量变成非负数后便结束等待,继续执行wait函数后面的任务!
*/
}
控制台:
2017-09-22 05:20:18.634 LMGCDTest[4968:385500] 等待前 <OS_dispatch_semaphore: 0x174093d80>
2017-09-22 05:20:18.635 LMGCDTest[4968:385989] task1 : <NSThread: 0x17426fa00>{number = 17, name = (null)}
2017-09-22 05:20:21.640 LMGCDTest[4968:385989] task1.1 : <NSThread: 0x17426fa00>{number = 17, name = (null)}
2017-09-22 05:20:28.640 LMGCDTest[4968:385990] task2: <NSThread: 0x17426fc00>{number = 18, name = (null)}
2017-09-22 05:20:28.641 LMGCDTest[4968:385990] 发信号 <OS_dispatch_semaphore: 0x174093d80>
2017-09-22 05:20:28.642 LMGCDTest[4968:385500] 等待后 <OS_dispatch_semaphore: 0x174093d80>
2017-09-22 05:20:31.650 LMGCDTest[4968:385990] task3: <NSThread: 0x17426fc00>{number = 18, name = (null)}
/**
创建了一个初使值为10的semaphore,每一次for循环都会创建一个新的线程,线程结束的时候会发送一个信号,线程创建之前会信号等待,所以当同时创建了10个线程之后,for循环就会阻塞,等待有线程结束之后会增加一个信号才继续执行,如此就形成了对并发的控制,如上就是一个并发数为10的一个线程队列。
*/
- (IBAction)test:(id)sender {
// semaphore 应用:可以控制并发量;可以使产生依赖
// 控制并发量
// dispatch_group_t group = dispatch_group_create();
// dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
// dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// for (int i = 1; i < 101; i++)
// {
// dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
//
// dispatch_group_async(group, queue, ^{
// NSLog(@" %i",i);
//
// // 请求路径
// NSURL *url = [NSURL URLWithString:@"https://idmsa.apple.com/IDMSWebAuth/login?appIdKey=891bd3417a7776362562d2197f89480a8547b108fd934911bcbea0110d07f757&path=%2Faccount%2F&rv=1"];
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
// // 创建请求对象
// NSURLRequest *reuqest = [[NSURLRequest alloc] initWithURL:url];
//
// // 发送请求
// [NSURLConnection sendAsynchronousRequest:reuqest queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//
// // 请求成功,发送信号
// dispatch_semaphore_signal(semaphore);
//
// }];
//
// });
// }
// dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
/*
dispatch_queue_t global_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 创建一个信号总量为10的信号
dispatch_semaphore_t sema = dispatch_semaphore_create(10);
for (int i=1;i<101; i++) {
// 每次执行循环前先执行wait,每次-1,10次后就变成0,第十一个及以后的任务会等待信号 >= 0
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_async(global_queue, ^{
// 请求路径
NSURL *url = [NSURL URLWithString:@"https://idmsa.apple.com/IDMSWebAuth/login?appIdKey=891bd3417a7776362562d2197f89480a8547b108fd934911bcbea0110d07f757&path=%2Faccount%2F&rv=1"];
// NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
// 创建请求对象
NSURLRequest *reuqest = [[NSURLRequest alloc] initWithURL:url];
NSLog(@"%d",i);
// 发送请求
[NSURLConnection sendAsynchronousRequest:reuqest queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
// 请求成功,发送信号
dispatch_semaphore_signal(sema);
}];
});
}
*/
dispatch_queue_t global_queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
// 创建一个信号总量为10的信号
dispatch_semaphore_t sema =dispatch_semaphore_create(10);
for (int i=1;i<101; i++) {
// 每次执行循环前先执行wait,每次-1,10次后就变成0,第十一个及以后的任务会等待信号 >= 0
dispatch_semaphore_wait(sema,DISPATCH_TIME_FOREVER);
dispatch_async(global_queue, ^{
NSLog(@"当前任务编号 ---> %d",i);
// 执行任务
sleep(2);
// 任务执行完毕,发送信号量
dispatch_semaphore_signal(sema);
});
}
}
控制台:
2017-09-22 05:21:02.290 LMGCDTest[4968:386057] 当前任务编号 ---> 1
2017-09-22 05:21:02.290 LMGCDTest[4968:386056] 当前任务编号 ---> 2
2017-09-22 05:21:02.292 LMGCDTest[4968:386090] 当前任务编号 ---> 3
2017-09-22 05:21:02.293 LMGCDTest[4968:386091] 当前任务编号 ---> 4
2017-09-22 05:21:02.294 LMGCDTest[4968:386092] 当前任务编号 ---> 5
2017-09-22 05:21:02.295 LMGCDTest[4968:386093] 当前任务编号 ---> 6
2017-09-22 05:21:02.296 LMGCDTest[4968:386094] 当前任务编号 ---> 7
2017-09-22 05:21:02.297 LMGCDTest[4968:386095] 当前任务编号 ---> 8
2017-09-22 05:21:02.297 LMGCDTest[4968:386096] 当前任务编号 ---> 9
2017-09-22 05:21:02.298 LMGCDTest[4968:386097] 当前任务编号 ---> 10
2017-09-22 05:21:04.295 LMGCDTest[4968:386091] 当前任务编号 ---> 11
2017-09-22 05:21:04.295 LMGCDTest[4968:386056] 当前任务编号 ---> 12
2017-09-22 05:21:04.296 LMGCDTest[4968:386090] 当前任务编号 ---> 13
2017-09-22 05:21:04.296 LMGCDTest[4968:386057] 当前任务编号 ---> 14
2017-09-22 05:21:04.299 LMGCDTest[4968:386093] 当前任务编号 ---> 15
2017-09-22 05:21:04.299 LMGCDTest[4968:386092] 当前任务编号 ---> 16
2017-09-22 05:21:04.300 LMGCDTest[4968:386096] 当前任务编号 ---> 17
2017-09-22 05:21:04.300 LMGCDTest[4968:386095] 当前任务编号 ---> 18
2017-09-22 05:21:04.300 LMGCDTest[4968:386094] 当前任务编号 ---> 19
2017-09-22 05:21:04.303 LMGCDTest[4968:386097] 当前任务编号 ---> 20
这里截取了前20个,任务都是每次10个为一组开始执行
@end