zoukankan      html  css  js  c++  java
  • GCD中的dispatch_set_target_queue的用法及作用 iOS

    (一),使用dispatch_set_target_queue更改Dispatch Queue的执行优先级

    dispatch_queue_create函数生成的DisPatch Queue不管是Serial DisPatch Queue还是Concurrent Dispatch Queue,执行的优先级都与默认优先级的Global Dispatch queue相同,如果需要变更生成的Dispatch Queue的执行优先级则需要使用dispatch_set_target_queue函数

    1 - (void)testTeagerQueue1 {
    2     dispatch_queue_t serialQueue = dispatch_queue_create("com.oukavip.www",NULL);
    3     dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0);
    4     
    5     dispatch_set_target_queue(serialQueue, globalQueue);
    6     // 第一个参数为要设置优先级的queue,第二个参数是参照物,既将第一个queue的优先级和第二个queue的优先级设置一样。
    7 }

    (二),使用dispatch_set_target_queue修改用户队列的目标队列,使多个serial queue在目标queue上一次只有一个执行

    首先,我们需要阐述一下生成多个Serial DisPatch Queue时的注意事项

    Serial DisPatch Queue是一个串行队列,只能同时执行1个追加处理(即任务),当用Dispatch_queue_create函数生成多个Serial DisPatch Queue时,每个Serial DisPatch Queue均获得一个线程,即多个Serial DisPatch Queue可并发执行,同时处理添加到各个Serial DisPatch Queue中的任务,但要注意如果过多地使用多线程,就会消耗大量内存,引起大量的上下文切换,大幅度降低系统的响应性能,所以我们只在为了避免多个线程更新相同资源导致数据竞争时,使用Serial DisPatch Queue

     第一种情况:使用dispatch_set_target_queue(Dispatch Queue1, Dispatch Queue2)实现队列的动态调度管理

     1 - (void)testTargetQueue2 {
     2     //创建一个串行队列queue1
     3     dispatch_queue_t queue1 = dispatch_queue_create("test.1", DISPATCH_QUEUE_SERIAL);
     4     //创建一个串行队列queue2
     5     dispatch_queue_t queue2 = dispatch_queue_create("test.2", DISPATCH_QUEUE_SERIAL);
     6     
     7     //使用dispatch_set_target_queue()实现队列的动态调度管理
     8     dispatch_set_target_queue(queue1, queue2);
     9     
    10     
    11 /*
    12  
    13     <*>dispatch_set_target_queue(Dispatch Queue1, Dispatch Queue2);
    14     那么dispatchA上还未运行的block会在dispatchB上运行。这时如果暂停dispatchA运行:
    15     
    16     <*>dispatch_suspend(dispatchA);
    17     这时则只会暂停dispatchA上原来的block的执行,dispatchB的block则不受影响。而如果暂停dispatchB的运行,则会暂停dispatchA的运行。
    18     
    19     这里只简单举个例子,说明dispatch队列运行的灵活性,在实际应用中你会逐步发掘出它的潜力。
    20     
    21     dispatch队列不支持cancel(取消),没有实现dispatch_cancel()函数,不像NSOperationQueue,不得不说这是个小小的缺憾
    22      
    23 */
    24     dispatch_async(queue1, ^{
    25         for (NSInteger i = 0; i < 10; i++) {
    26             NSLog(@"queue1:%@, %ld", [NSThread currentThread], i);
    27             [NSThread sleepForTimeInterval:0.5];
    28             if (i == 5) {
    29                 dispatch_suspend(queue2);
    30             }
    31         }
    32     });
    33     
    34     dispatch_async(queue1, ^{
    35         for (NSInteger i = 0; i < 100; i++) {
    36             NSLog(@"queue1:%@, %ld", [NSThread currentThread], i);
    37         }
    38         
    39     });
    40     
    41     dispatch_async(queue2, ^{
    42         for (NSInteger i = 0; i < 100; i++) {
    43             NSLog(@"queue2:%@, %ld", [NSThread currentThread], i);
    44         }
    45     });
    46     
    47 }

    第二种情况:使用dispatch_set_target_queue将多个串行的queue指定到了同一目标,那么着多个串行queue在目标queue上就是同步执行的,不再是并行执行。

    - (void)testTargetQueue {
        //1.创建目标队列
        dispatch_queue_t targetQueue = dispatch_queue_create("test.target.queue", DISPATCH_QUEUE_SERIAL);
        
        //2.创建3个串行队列
        dispatch_queue_t queue1 = dispatch_queue_create("test.1", DISPATCH_QUEUE_SERIAL);
        dispatch_queue_t queue2 = dispatch_queue_create("test.2", DISPATCH_QUEUE_SERIAL);
        dispatch_queue_t queue3 = dispatch_queue_create("test.3", DISPATCH_QUEUE_SERIAL);
        
        //3.将3个串行队列分别添加到目标队列
        dispatch_set_target_queue(queue1, targetQueue);
        dispatch_set_target_queue(queue2, targetQueue);
        dispatch_set_target_queue(queue3, targetQueue);
        
        
        dispatch_async(queue1, ^{
            NSLog(@"1 in");
            [NSThread sleepForTimeInterval:3.f];
            NSLog(@"1 out");
        });
        
        dispatch_async(queue2, ^{
            NSLog(@"2 in");
            [NSThread sleepForTimeInterval:2.f];
            NSLog(@"2 out");
        });
        dispatch_async(queue3, ^{
            NSLog(@"3 in");
            [NSThread sleepForTimeInterval:1.f];
            NSLog(@"3 out");
        });
    }
  • 相关阅读:
    学习git之路--1
    No input file specified. phpStudy nginx报错解决方案
    nginx隐藏tp路由index.php
    tp5命令行
    生成器
    php 解密小程序获取unionid
    根据GUID获取实例
    用SQL将数字转换为中文数字
    TFS无法确定工作区解决方案
    利用SQL语句产生分组序号
  • 原文地址:https://www.cnblogs.com/denz/p/5214297.html
Copyright © 2011-2022 走看看