GCD中的dispatch_set_target_queue的用法及作用


(一),使用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");
    });
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM