美文网首页
关于IOS中GCD的理解

关于IOS中GCD的理解

作者: 西门淋雨 | 来源:发表于2018-09-05 17:47 被阅读20次

Dispatch Queue 分为两类:Serial Diapatch Queue 和 Concurrent Dispatch Queue.

Serial Diapatch Queue:等待现在执行中处理结束。
Concurrent Dispatch Queue:不等待现在执行中处理结束


D81D6A6A-A3BE-43D8-941A-8B6F0475904A.png
CA5A8008-F9B4-4624-970E-0D65B0C45F5A.png 186F9865-9559-41BB-B4A5-D681BBEB0AEC.png
SerialDispatchQueue-手动创建
//SerialDispatchQueueTest-等待结果按照顺序执行
- (IBAction)serialDispatchQueueTest:(id)sender{
    //创建一个SerialDispatchQueue,主要是用于防止资源的竞争,一个线程处使用完资源,然后另外一个才能继续使用
    dispatch_queue_t mySerialDispatchQueue =  dispatch_queue_create("com.example.gcd,serialDiapatchQueue", NULL);
    dispatch_async(mySerialDispatchQueue, ^{
        sleep(10);
        NSLog(@"mySerialDispatchQueue1-执行完毕");
    });
    dispatch_async(mySerialDispatchQueue, ^{
        sleep(8);
        NSLog(@"mySerialDispatchQueue2-执行完毕");
    });
    dispatch_async(mySerialDispatchQueue, ^{
        sleep(6);
        NSLog(@"mySerialDispatchQueue3-执行完毕");
    });
    dispatch_async(mySerialDispatchQueue, ^{
        sleep(4);
        NSLog(@"mySerialDispatchQueue4-执行完毕");
    });
    dispatch_async(mySerialDispatchQueue, ^{
        sleep(2);
        NSLog(@"mySerialDispatchQueue5-执行完毕");
    });
    //输出的结果
    /*
     2018-09-05 10:51:48.734387+0800 OCProject[89452:4426497] mySerialDispatchQueue1-执行完毕
     2018-09-05 10:51:56.738496+0800 OCProject[89452:4426497] mySerialDispatchQueue2-执行完毕
     2018-09-05 10:52:02.740314+0800 OCProject[89452:4426497] mySerialDispatchQueue3-执行完毕
     2018-09-05 10:52:06.744937+0800 OCProject[89452:4426497] mySerialDispatchQueue4-执行完毕
     2018-09-05 10:52:08.750614+0800 OCProject[89452:4426497] mySerialDispatchQueue5-执行完毕
     */
    //可以看出,创建1个SerialDispatchQueue,添加不同的任务,按照顺序执行。
}
ConcurrentDispatchQueue-手动创建
- (IBAction)concurrentDispatchQueueTest:(id)sender{
    dispatch_queue_t myConsurrentDiapatchQueue = dispatch_queue_create("com.example.gcd,serialDiapatchQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(myConsurrentDiapatchQueue, ^{
        sleep(4);
        NSLog(@"myConsurrentDiapatchQueue-执行完毕");
        dispatch_async([self mainQueue], ^{
            NSLog(@"回到主线程===1");
        });
    });
    dispatch_async(myConsurrentDiapatchQueue, ^{
        sleep(2);
        NSLog(@"myConsurrentDiapatchQueue-执行完毕");
        dispatch_async([self mainQueue], ^{
            NSLog(@"回到主线程===2");
        });
    });
}
SerialDispatchQueue-直接获取
/*
 *获取mian dispatch queue
 *dispatch_get_main_queue() 是在主线程执行的 Serial Diapatch Queue,主线程只有一个,所以 Main dispatch Queue 是 Serial Diapatch Queue
 */
- (dispatch_queue_t)mainQueue{
    return dispatch_get_main_queue();
}
ConcurrentDispatchQueue-直接获取
/*获取 global dispatch queue
 *dispatch_get_global_queue 是所有应用程序都能使用的Concurrent Queue,没必要自己生成只需要获取就可以使用。
 */
- (dispatch_queue_t)gloableQueue{
    return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
}
//直接获取使用Concurrent Dispatch Queue
- (IBAction)concurrentDispatchQueueTest2:(id)sender{
    dispatch_async([self gloableQueue], ^{
        sleep(5);
        NSLog(@"获取gloable1,并发执行==");
        dispatch_async([self mainQueue], ^{
            NSLog(@"回到主线程===1");
        });
    });
    
    dispatch_async([self gloableQueue], ^{
        sleep(3);
        NSLog(@"获取gloable2,并发执行==");
        dispatch_async([self mainQueue], ^{
            NSLog(@"回到主线程===2");
        });
    });
    
}
创建个多个SerialDispatchQueue,也可以实现并发操作
//SerialDispatchQueueTest-不用等待结果,并发执行
- (IBAction)serialDispatchQueueTest2:(id)sender{
    //创建多个SerialDispatchQueue
    dispatch_queue_t mySerialDispatchQueue1 =  dispatch_queue_create("com.example.gcd,serialDiapatchQueue2", NULL);
    dispatch_queue_t mySerialDispatchQueue2 =  dispatch_queue_create("com.example.gcd,serialDiapatchQueue3", NULL);
    dispatch_queue_t mySerialDispatchQueue3 =  dispatch_queue_create("com.example.gcd,serialDiapatchQueue4", NULL);
    dispatch_queue_t mySerialDispatchQueue4 =  dispatch_queue_create("com.example.gcd,serialDiapatchQueue5", NULL);
    dispatch_queue_t mySerialDispatchQueue5 =  dispatch_queue_create("com.example.gcd,serialDiapatchQueue6", NULL);

    dispatch_async(mySerialDispatchQueue1, ^{
        sleep(10);
        NSLog(@"mySerialDispatchQueue1-执行完毕");
    });
    dispatch_async(mySerialDispatchQueue2, ^{
        sleep(8);
        NSLog(@"mySerialDispatchQueue2-执行完毕");
    });
    dispatch_async(mySerialDispatchQueue3, ^{
        sleep(6);
        NSLog(@"mySerialDispatchQueue3-执行完毕");
    });
    dispatch_async(mySerialDispatchQueue4, ^{
        sleep(4);
        NSLog(@"mySerialDispatchQueue4-执行完毕");
    });
    dispatch_async(mySerialDispatchQueue5, ^{
        sleep(2);
        NSLog(@"mySerialDispatchQueue5-执行完毕");
    });
    //输出的结果
    /*
     2018-09-05 10:50:33.727306+0800 OCProject[89411:4425494] mySerialDispatchQueue5-执行完毕
     2018-09-05 10:50:35.727295+0800 OCProject[89411:4425364] mySerialDispatchQueue4-执行完毕
     2018-09-05 10:50:37.726063+0800 OCProject[89411:4425373] mySerialDispatchQueue3-执行完毕
     2018-09-05 10:50:39.725696+0800 OCProject[89411:4425371] mySerialDispatchQueue2-执行完毕
     2018-09-05 10:50:41.727550+0800 OCProject[89411:4425365] mySerialDispatchQueue1-执行完毕
     */
    //可以看出,创建个多个SerialDispatchQueue,可以并发的执行,谁的休眠时间短谁先执行完毕。
}
DispatchGroup
实际的情况可能是多个线程都在并发处理,但是希望这些并发都结束后有一个具体的操作
//dispatchGroup
//实际的情况可能是多个线程都在并发处理,但是希望这些并发都结束后有一个具体的操作
- (IBAction)dispatchGroupTest:(id)sender{
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, [self gloableQueue], ^{
        sleep(6);
        NSLog(@"block-1");
    });
    dispatch_group_async(group, [self gloableQueue], ^{
        sleep(4);
        NSLog(@"block-2");
    });
    dispatch_group_async(group, [self gloableQueue], ^{
        sleep(5);
        NSLog(@"block-3");
    });
    
    dispatch_group_notify(group, [self mainQueue], ^{
        NSLog(@"全部任务结束后,回到主线程--");
    });
    //或者也可以使用 dispatch_group_wait,推荐使用dispatch_group_notify
//    long result =  dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
//    if (result == 0) {
//        NSLog(@"全部任务结束后,回到主线程--2");
//    }else{
//        NSLog(@"全部任务结束后,回到主线程--3");
//    }
    //打印结果
    /*
    2018-09-05 14:33:41.861183+0800 OCProject[92527:4569666] block-2
    2018-09-05 14:33:42.860655+0800 OCProject[92527:4569662] block-3
    2018-09-05 14:33:43.858538+0800 OCProject[92527:4569684] block-1
    2018-09-05 14:33:43.858840+0800 OCProject[92527:4569602] 全部任务结束后,回到主线程--
    */
}
dispatch_barrier_async:写入的操作时,会等待其他进行中的线程结束后才开始,然后自身结束后,恢复进程的管理,开始后面的进程:
原始状态--dispatch_barrier_async-原始状态
//写入的操作时,会等待其他进行中的线程结束后才开始,然后自身结束后,恢复进程的管理,开始后面的进程。
//原始状态--dispatch_barrier_async-原始状态
- (IBAction)dispatch_barrier_async:(id)sender{
    dispatch_async([self gloableQueue], ^{
        sleep(2);
        NSLog(@"读取操作=1");
    });
    dispatch_async([self gloableQueue], ^{
        NSLog(@"读取操作=2");
    });
    dispatch_async([self gloableQueue], ^{
        NSLog(@"读取操作=3");
    });
    dispatch_async([self gloableQueue], ^{
        NSLog(@"读取操作=4");
    });
    dispatch_async([self gloableQueue], ^{
        NSLog(@"读取操作=5");
    });
    dispatch_barrier_async([self gloableQueue], ^{
        sleep(5);
        NSLog(@"写入操作=========");
    });
    dispatch_async([self gloableQueue], ^{
        NSLog(@"读取操作=6");
    });
    dispatch_async([self gloableQueue], ^{
        sleep(3);
        NSLog(@"读取操作=7");
    });
    dispatch_async([self gloableQueue], ^{
        NSLog(@"读取操作=8");
    });
    dispatch_async([self gloableQueue], ^{
        NSLog(@"读取操作=9");
    });
}
0C840EC2-811A-4A3D-8B06-67037F8400F3.png
dispatch_apply:等待全部处理结执行束
- (IBAction)dispatch_apply:(id)sender {
    NSArray *arrry = @[@"lj",@"hj",@"sd",@"ew",@"cs",@"ad",@"asd",@"ee"];
    dispatch_apply(arrry.count, [self gloableQueue], ^(size_t index) {
        NSLog(@"index==%ld,content==%@",index,arrry[index]);
    });
    NSLog(@"done==");
    
    dispatch_async([self gloableQueue], ^{
        dispatch_apply([arrry count], [self gloableQueue], ^(size_t index) {
            NSLog(@"index2==%ld,content2==%@",index,arrry[index]);
        });
        dispatch_async([self mainQueue], ^{
            NSLog(@"done==2");
        });
    });
    
}
/*
 2018-09-05 16:03:06.583186+0800 OCProject[93730:4631487] index==2,content==sd
 2018-09-05 16:03:06.583178+0800 OCProject[93730:4631316] index==1,content==hj
 2018-09-05 16:03:06.583175+0800 OCProject[93730:4631252] index==0,content==lj
 2018-09-05 16:03:06.583224+0800 OCProject[93730:4631486] index==3,content==ew
 2018-09-05 16:03:06.583376+0800 OCProject[93730:4631487] index==4,content==cs
 2018-09-05 16:03:06.583377+0800 OCProject[93730:4631316] index==6,content==asd
 2018-09-05 16:03:06.583377+0800 OCProject[93730:4631252] index==5,content==ad
 2018-09-05 16:03:06.583468+0800 OCProject[93730:4631486] index==7,content==ee
 2018-09-05 16:03:06.583752+0800 OCProject[93730:4631252] done==
 */
//done==肯定是最后输出
信号
- (IBAction)dispatchSemaphore:(id)sender{
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];
    
    for (NSInteger i =0; i < 100000; i ++ ) {
        dispatch_async([self gloableQueue], ^{
            //检测到信号不为0则可以继续执行,然后信号量-1
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//信号-1
            [array addObject:[NSNumber numberWithLong:i]];
            //执行完操作后,信号+1,然后继续循环执行
            dispatch_semaphore_signal(semaphore);//信号+1
        });
    }
}
//创建了两个任务信号,多余的任务需要等待信号释放才能执行
- (IBAction)dispatchSemaphore2:(id)sender{
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    dispatch_async([self gloableQueue], ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"task-1");
        sleep(2);
        NSLog(@"task-1-finish");
        dispatch_semaphore_signal(semaphore);
    });
    dispatch_async([self gloableQueue], ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"task-2");
        sleep(2);
        NSLog(@"task-2-finish");
        dispatch_semaphore_signal(semaphore);
    });
    dispatch_async([self gloableQueue], ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"task-3");
        sleep(2);
        NSLog(@"task-3-finish");
        dispatch_semaphore_signal(semaphore);
    });
}
/*
 2018-09-05 18:47:41.270014+0800 OCProject[1148:4748195] task-1
 2018-09-05 18:47:41.270089+0800 OCProject[1148:4748209] task-3
 2018-09-05 18:47:43.273053+0800 OCProject[1148:4748209] task-3-finish
 2018-09-05 18:47:43.273053+0800 OCProject[1148:4748195] task-1-finish
 2018-09-05 18:47:43.273330+0800 OCProject[1148:4748510] task-2
 2018-09-05 18:47:45.278272+0800 OCProject[1148:4748510] task-2-finish

 */

相关文章

  • 关于IOS中GCD的理解

    Dispatch Queue 分为两类:Serial Diapatch Queue 和 Concurrent Di...

  • ios中关于GCD的理解

    1. 多线程的底层实现? 1> 首先搞清楚什么是线程、什么是多线程 2> Mach是第一个以多线程方式处理任务的系...

  • (链接)GCD

    一 通过GCD中的dispatch_barrier_(a)sync所谓等待的理解 二 iOS-GCD之初,disP...

  • 理解GCD

    (1)博客:深入理解GCD 理解iOS中的线程池 多线程理解 ?:(1)信号量--...

  • OC-多线程GCD

    参考:GCD源码深入理解 GCDiOS多线程--彻底学会多线程之『GCD』关于iOS多线程,我说,你听,没准你就懂...

  • 理解iOS中的GCD

    关于GCD,大体上要说的有这些: 多线程 一个千篇一律的应届生面试题:什么是进程和线程,以及二者的区别和联系 进程...

  • 轻松学iOS多线程之 GCD 的常用函数

    关于 iOS 多线程中 GCD 的基础知识已在上一篇文章中详细说明,请参看《轻松学iOS多线程之 GCD 的基本使...

  • 拨开GCD的面纱

    之前我在博客中也说过了,关于GCD和block是很多新手的两大拦路虎,下面谈谈GCD。 GCD是iOS中异步执行任...

  • ios 中GCD总结

    ios 中GCD总结

  • iOS-知识点

    五个案例让你明白GCD死锁:http://ios.jobbole.com/82622/ iOS开发中多线程间关于锁...

网友评论

      本文标题:关于IOS中GCD的理解

      本文链接:https://www.haomeiwen.com/subject/knzawftx.html