zoukankan      html  css  js  c++  java
  • GCD系列 之(二): 多核心的性能

    全局队列的并发执行

    for(id obj in array)
        [self doSomethingIntensiveWith:obj];

          假设,每个元素要做的事情-doSomethingIntensiveWith: 是线程安全的且可以同时并发执行多个。一个array通常包含多个元素,这样的话,我们可以很简单地使用GCD来平行运算:

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    for(id obj in array)
        dispatch_async(queue, ^{
            [self doSomethingIntensiveWith:obj];
        });

         这样充分利用了多核系统的性能。

         有时候,我们需要在完成对数组的每一个数据操作之后,再对数组整体进行操作,那么就有一个问题,什么时候,这些数组的数据的并发执行任务都完成了?

    dispatch group     

          解决这个问题的一种方法是使用dispatch group。一个dispatch group可以用来将多个block组成一组以监测这些Block全部完成或者等待全部完成时发出的消息。使用函数dispatch_group_create来创建,然后使用函数dispatch_group_async来将block提交至一个dispatch queue,同时将它们添加至一个组。

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    for(id obj in array)
        dispatch_group_async(group, queue, ^{
            [self doSomethingIntensiveWith:obj];
        });
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    dispatch_release(group);
     
    [self doSomethingWith:array];

    如果后续的对数组的整体处理也是可以异步的,那么可以这样:

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    for(id obj in array)
        dispatch_group_async(group, queue, ^{
            [self doSomethingIntensiveWith:obj];
        });
    dispatch_group_notify(group, queue, ^{
        [self doSomethingWith:array];
    });
    dispatch_release(group);

    如果对数组的处理-doSomethingWith:需要在主线程中执行,比如操作GUI,那么我们只要将main queue而非全局队列传给dispatch_group_notify函数就行了。

    dispatch_apply

    同步执行,GCD提供了一个简化方法叫做dispatch_apply。该函数按指定的次数将指定的Block追加到指定的Dispatch Queue中,指定的次数的Block将会被异步执行,dispatch_apply函数会等待全部处理执行结束,接着进行后面的代码序列。

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_apply([array count], queue, ^(size_t index){
            [self doSomethingIntensiveWith:[array objectAtIndex:index]];
        });
        [self doSomethingWith:array];

    dispatch_apply函数是没有异步版本的,实现异步要用dispatch_async函数将所有代码推到后台实现异步。

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        dispatch_apply([array count], queue, ^(size_t index){
            [self doSomethingIntensiveWith:[array objectAtIndex:index]];
        });
        [self doSomethingWith:array];
    });
    dispatch_queue_t queue = dispatch_get_global_queu(0, 0);
    dispatch_apply(10, queue, ^(size_t index){
    NSLog(@"%zu", index);
    });
    NSLog(@"done");

    执行结果:

    4
    3
    5
    0
    2
    1
    7
    6
    9
    8
    done
    • 第一个参数为重复次数
    • 第二个参数为追加对象的Dispatch Queue
    • 第三个参数为追加的处理。

    由于dispatch_apply函数与dispatch_sync函数相同,会等待处理执行结束,因此推荐在dispatch_async函数中非同步地执行dispatch_apply函数

    NSArray *array = @[@"1", @"2", @"3", @"4", @"5", @"6"];
        dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
        dispatch_async(queue, ^{
    
            dispatch_apply([array count], queue, ^(size_t index) {
    
                NSLog(@"%zu : %@", index, [array objectAtIndex:index]);
            });
    
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"currentThread = %@", [NSThread currentThread]);
                NSLog(@"done");
            });
        });
  • 相关阅读:
    直道相思了无益 你既无心我便休
    c#与XML
    ASP.NET读取Excel文件的三大方法浅析
    当前标识(NT AUTHORITY\NETWORK SERVICE)没有对“C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files”的写访问权限。
    比较这2段HTML代码
    编码的一点思维
    代码修改的一个范例
    在aspx.cs中不出现中文?
    规则先行
    设计模式——UML简介
  • 原文地址:https://www.cnblogs.com/Jordandan/p/6203226.html
Copyright © 2011-2022 走看看