Dispatch

  • Managing Units of Work(管理工作單位)

調(diào)度塊允許您直接配置隊(duì)列中各個(gè)工作單元的屬性。它們還允許您處理個(gè)別工作單位,以等待其完成,并通知其完成和/或取消它們

  • dispatch_block_t

1.這是提交給dispatch隊(duì)列的塊的原型,它不帶參數(shù),也沒(méi)有返回值。
2.創(chuàng)建block的方式有兩種

  • 2.1:dispatch_block_create

2.1.1

  • 2.2:dispatch_block_create_with_qos_class
dispatch_block_t blockT=dispatch_block_create(0, ^{
        NSLog(@"11111");
    });
    NSLog(@"22222");
    dispatch_queue_t myQueue=dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(myQueue, blockT);
    NSLog(@"33333");
    
    //第三個(gè)參數(shù)設(shè)置成1 居然在下面dispatch_async(myQueue, blockY);處奔潰,不知道是不是死鎖,暫不知原因
    dispatch_block_t blockY=dispatch_block_create_with_qos_class(1, QOS_CLASS_USER_INTERACTIVE, 0, ^{
        NSLog(@"44444");
    });
    
    dispatch_async(myQueue, blockY);
    NSLog(@"5555");

參數(shù):
參數(shù)1:是一個(gè)dispatch_block_flags枚舉
DISPATCH_BLOCK_BARRIER
DISPATCH_BLOCK_DETACHED
DISPATCH_BLOCK_ASSIGN_CURRENT
DISPATCH_BLOCK_NO_QOS_CLASS
DISPATCH_BLOCK_INHERIT_QOS_CLASS
DISPATCH_BLOCK_ENFORCE_QOS_CLASS
并不太清楚具體原因
參數(shù)2.而 qos_class_t 是一種枚舉,有以下類型:
QOS_CLASS_USER_INTERACTIVE: user interactive 等級(jí)表示任務(wù)需要被立即執(zhí)行,用來(lái)在響應(yīng)事件之后更新 UI,來(lái)提供好的用戶體驗(yàn)。這個(gè)等級(jí)最好保持小規(guī)模。
QOS_CLASS_USER_INITIATED: user initiated 等級(jí)表示任務(wù)由 UI 發(fā)起異步執(zhí)行。適用場(chǎng)景是需要及時(shí)結(jié)果同時(shí)又可以繼續(xù)交互的時(shí)候。
QOS_CLASS_DEFAULT: default 默認(rèn)優(yōu)先級(jí)
QOS_CLASS_UTILITY: utility 等級(jí)表示需要長(zhǎng)時(shí)間運(yùn)行的任務(wù),伴有用戶可見(jiàn)進(jìn)度指示器。經(jīng)常會(huì)用來(lái)做計(jì)算,I/O,網(wǎng)絡(luò),持續(xù)的數(shù)據(jù)填充等任務(wù)。這個(gè)任務(wù)節(jié)能。
QOS_CLASS_BACKGROUND: background 等級(jí)表示用戶不會(huì)察覺(jué)的任務(wù),使用它來(lái)處理預(yù)加載,或者不需要用戶交互和對(duì)時(shí)間不敏感的任務(wù)。
QOS_CLASS_UNSPECIFIED: unspecified 未指明
參數(shù)3:

  • dispatch_function_t

1.提交調(diào)度隊(duì)列的函數(shù)原型
2.函數(shù)可以接受一個(gè)dispatch_function_t類型作為參數(shù),同時(shí)接受一個(gè)指向您提供上下文數(shù)據(jù)。調(diào)用調(diào)度函數(shù)時(shí),將上下文數(shù)據(jù)的指針作為參數(shù)傳遞給函數(shù)。對(duì)上下文數(shù)據(jù)的指針未經(jīng)修改而傳遞給您的函數(shù),您有責(zé)任確保指針是有效的

  • dispatch_block_perform

1.從指定的塊和標(biāo)志創(chuàng)建、同步執(zhí)行和釋放調(diào)度塊
2.在不需要對(duì)指定塊的堆或一個(gè)新塊對(duì)象的分配進(jìn)行復(fù)制的情況下,可以更有效地實(shí)現(xiàn)此功能
3.相當(dāng)于如下代碼

//調(diào)用
NSLog(@"11111");
    dispatch_block_perform(0, ^{
       
        NSLog(@"2222");
    });
    NSLog(@"3333");
//dispatch_block_perform相當(dāng)于如下
dispatch_block_t b = dispatch_block_create(flags, block);
b();
Block_release(b)
  • dispatch_block_wait

1.同步地等待,直到執(zhí)行指定的調(diào)度塊已經(jīng)完成,或者直到指定的超時(shí)已經(jīng)過(guò)去。
2.該函數(shù)會(huì)阻塞當(dāng)前線程進(jìn)行等待。傳入需要設(shè)置的 block 和等待時(shí)間 timeout 。timeout 參數(shù)表示函數(shù)在等待 block 執(zhí)行完畢時(shí),應(yīng)該等待多久。如果執(zhí)行 block 所需的時(shí)間小于 timeout ,則返回 0,否則返回非 0 值。此參數(shù)也可以取常量DISPATCH_TIME_FOREVER ,這表示函數(shù)會(huì)一直等待 block 執(zhí)行完,而不會(huì)超時(shí)??梢允褂?dispatch_time 函數(shù)和 DISPATCH_TIME_NOW 常量來(lái)方便的設(shè)置具體的超時(shí)時(shí)間。
3.如果 block 執(zhí)行完成, dispatch_block_wait 就會(huì)立即返回。不能使用 dispatch_block_wait 來(lái)等待同一個(gè) block 的多次執(zhí)行全部結(jié)束;這種情況可以考慮使用dispatch_group_wait 來(lái)解決。也不能在多個(gè)線程中,同時(shí)等待同一個(gè) block 的結(jié)束。同一個(gè) block 只能執(zhí)行一次,被等待一次。
4.注意:因?yàn)?dispatch_block_wait 會(huì)阻塞當(dāng)前線程,所以不應(yīng)該放在主線程中調(diào)用

dispatch_queue_t concurrentQuene = dispatch_queue_create("concurrentQuene", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(concurrentQuene, ^{
        dispatch_queue_t allTasksQueue = dispatch_queue_create("allTasksQueue", DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_block_t block = dispatch_block_create(0, ^{
            NSLog(@"開(kāi)始執(zhí)行");
            [NSThread sleepForTimeInterval:3];
            NSLog(@"結(jié)束執(zhí)行");
        });
        
        dispatch_async(allTasksQueue, block);
        // 等待時(shí)長(zhǎng),10s 之后超時(shí)
        dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC));
        long resutl = dispatch_block_wait(block, timeout);
        if (resutl == 0) {
            NSLog(@"執(zhí)行成功");
        } else {
            NSLog(@"執(zhí)行超時(shí)");
        }
    });
  • dispatch_block_notify

1.可理解為監(jiān)聽(tīng)
2.在指定的調(diào)度塊執(zhí)行完成時(shí),調(diào)度一個(gè)通知塊提交給隊(duì)列
3.該函數(shù)接收三個(gè)參數(shù),第一個(gè)參數(shù)是需要監(jiān)視的 block,第二個(gè)參數(shù)是監(jiān)聽(tīng)的 block 執(zhí)行結(jié)束之后要提交執(zhí)行的隊(duì)列 queue,第三個(gè)參數(shù)是待加入到隊(duì)列中的 block。 和 dispatch_block_wait 的不同之處在于:dispatch_block_notify 函數(shù)不會(huì)阻塞當(dāng)前線程

  • dispatch_block_cancel

1.這個(gè)函數(shù)用異步的方式取消指定的 block

dispatch_queue_t myQueue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_SERIAL);
    // 耗時(shí)任務(wù)
    dispatch_block_t firstBlock = dispatch_block_create(0, ^{
        NSLog(@"開(kāi)始第一個(gè)任務(wù):%d",[NSThread isMainThread]);
        [NSThread sleepForTimeInterval:1.5f];
        NSLog(@"結(jié)束第一個(gè)任務(wù)");
    });
    // 耗時(shí)任務(wù)
    dispatch_block_t secBlock = dispatch_block_create(0, ^{
        NSLog(@"開(kāi)始第二個(gè)任務(wù):%d",[NSThread isMainThread]);
        [NSThread sleepForTimeInterval:2.f];
        NSLog(@"結(jié)束第二個(gè)任務(wù)");
    });
    dispatch_async(myQueue, firstBlock);
    dispatch_async(myQueue, secBlock);
    // 等待 1s,讓第一個(gè)任務(wù)開(kāi)始運(yùn)行,因?yàn)閙yQueue是串行隊(duì)列,遵守fifo先進(jìn)先出的規(guī)則,所以必須先執(zhí)行完block1,才能執(zhí)行block2
    [NSThread sleepForTimeInterval:1];
    NSLog(@"休眠:%d",[NSThread isMainThread]);
    dispatch_block_cancel(firstBlock);
    NSLog(@"準(zhǔn)備取消第一個(gè)任務(wù)");
    dispatch_block_cancel(secBlock);
    NSLog(@"準(zhǔn)備取消第二個(gè)任務(wù)");
    /*
     打印的結(jié)果為:
     2017-07-06 18:32:04.046 多線程-GCD[6427:205689] 開(kāi)始第一個(gè)任務(wù):0
     2017-07-06 18:32:05.047 多線程-GCD[6427:205642] 休眠:1
     2017-07-06 18:32:05.047 多線程-GCD[6427:205642] 準(zhǔn)備取消第一個(gè)任務(wù)
     2017-07-06 18:32:05.047 多線程-GCD[6427:205642] 準(zhǔn)備取消第二個(gè)任務(wù)
     2017-07-06 18:32:05.547 多線程-GCD[6427:205689] 結(jié)束第一個(gè)任務(wù)
     可見(jiàn) dispatch_block_cancel 對(duì)已經(jīng)在執(zhí)行的任務(wù)不起作用,只能取消尚未執(zhí)行的任務(wù)
     */
  • dispatch_block_testcancel

1.測(cè)試給定的調(diào)度塊是否已被取消
2.如果取消調(diào)度塊,則返回一個(gè)非零值,否則為零

  • Prioritizing Work and Specifying Quality of Service(優(yōu)先工作和指定服務(wù)質(zhì)量

)

  • Dispatch Queue Priorities

1.用于選擇適當(dāng)?shù)娜植l(fā)隊(duì)列(global concurrent queue)
1.1 DISPATCH_QUEUE_PRIORITY_HIGH:這個(gè)常數(shù)映射到 QOS_CLASS_USER_INITIATED類
發(fā)送到隊(duì)列的項(xiàng)目以高優(yōu)先級(jí)運(yùn)行;隊(duì)列在任何默認(rèn)優(yōu)先級(jí)或低優(yōu)先級(jí)隊(duì)列之前調(diào)度執(zhí)行
1.2 DISPATCH_QUEUE_PRIORITY_DEFAULT:這個(gè)常數(shù)映射到 QOS_CLASS_DEFAULT類
發(fā)送到隊(duì)列的項(xiàng)目以默認(rèn)優(yōu)先級(jí)運(yùn)行;隊(duì)列在所有高優(yōu)先級(jí)隊(duì)列已排定之后執(zhí)行調(diào)度,但在調(diào)度任何低優(yōu)先級(jí)隊(duì)列之前
1.3 DISPATCH_QUEUE_PRIORITY_LOW:這個(gè)常數(shù)映射到 QOS_CLASS_UTILITY類
發(fā)送到隊(duì)列的項(xiàng)目以低優(yōu)先級(jí)運(yùn)行;隊(duì)列在所有默認(rèn)優(yōu)先級(jí)和高優(yōu)先級(jí)隊(duì)列已排定之后執(zhí)行調(diào)度
1.4 DISPATCH_QUEUE_PRIORITY_BACKGROUND:這個(gè)常數(shù)映射到QOS_CLASS_BACKGROUND類
發(fā)送到隊(duì)列的項(xiàng)目以后臺(tái)優(yōu)先級(jí)運(yùn)行;隊(duì)列在所有高優(yōu)先級(jí)隊(duì)列被調(diào)度后執(zhí)行調(diào)度,系統(tǒng)在其優(yōu)先級(jí)為后臺(tái)狀態(tài)設(shè)置的線程上運(yùn)行項(xiàng)目。這樣一個(gè)線程的優(yōu)先級(jí)最低,任何磁盤I/O是節(jié)流,減少對(duì)系統(tǒng)的影響

2.在MacOS 10.10以后,利用QoS類代替。有關(guān)更多信息,請(qǐng)參見(jiàn)服務(wù)質(zhì)量類(QoS)

  • dispatch_qos_class_t
  • dispatch_queue_priority_t
  • dispatch_queue_get_qos_class
  • dispatch_queue_attr_make_with_qos_class

如上這幾個(gè),官方文檔并沒(méi)有做過(guò)多介紹,了解就行

  • Using Dispatch Groups(利用調(diào)度組)

分組塊允許聚合同步。您的應(yīng)用程序可以提交多個(gè)塊,并在它們?nèi)客瓿蓵r(shí)跟蹤它們,即使它們可能在不同的隊(duì)列上運(yùn)行。當(dāng)所有指定的任務(wù)都完成后,你再需要做什么行為時(shí),這種類是有幫助的

  • dispatch_group_t

1.提交一組塊對(duì)象給隊(duì)做為異步調(diào)用
2.調(diào)度組是監(jiān)視一組塊的機(jī)制。應(yīng)用程序可以根據(jù)需要同步或異步監(jiān)視組中的塊。通過(guò)擴(kuò)展,一個(gè)組可以用于對(duì)依賴于其他任務(wù)完成的代碼進(jìn)行同步。
注意,組中的塊可以在不同的隊(duì)列上運(yùn)行,并且每個(gè)單獨(dú)的塊可以向組添加更多的塊

  • dispatch_group_async

1.將block(任務(wù))提交到指定的隊(duì)列中,并且將次任務(wù)放到(關(guān)聯(lián))指定的group,block將異步執(zhí)行
2.參數(shù)
group:要關(guān)聯(lián)的組。該組由系統(tǒng)保留,直到該塊運(yùn)行完成為止。此參數(shù)不能為空
queue:為異步調(diào)用提交塊對(duì)象的調(diào)度隊(duì)列。隊(duì)列被系統(tǒng)保留,直到該塊運(yùn)行到完成為止。此參數(shù)不能為空
block:異步執(zhí)行的塊對(duì)象。這個(gè)函數(shù)執(zhí)行代表調(diào)用者的block_copy和block_release

  • dispatch_group_async_f

1.這個(gè)方法跟dispatch_group_async差不多,只是第三個(gè)參數(shù)為c語(yǔ)言函數(shù)

  • dispatch_group_notify_f

1.當(dāng)group中的任務(wù)都完成以后會(huì)執(zhí)行block.注意這句代碼要加到所有任務(wù)提交之后才管用.參數(shù)queue代表block會(huì)提交到哪個(gè)隊(duì)列中

dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t conCurrentQueue =  dispatch_queue_create("conCurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, serialQueue, ^{
        NSLog(@"串行隊(duì)列任務(wù)一開(kāi)始");
        [NSThread sleepForTimeInterval:2];
        
        NSLog(@"串行隊(duì)列任務(wù)一快結(jié)束:%@",[NSThread currentThread]);
    });
    dispatch_group_async(group, serialQueue, ^{
        NSLog(@"串行隊(duì)列任務(wù)二開(kāi)始");
        [NSThread sleepForTimeInterval:2];
        
        NSLog(@"串行隊(duì)列任務(wù)二快結(jié)束:%@",[NSThread currentThread]);
    });
    
    dispatch_group_async(group, conCurrentQueue, ^{
       
        NSLog(@"并行隊(duì)列任務(wù)二開(kāi)始");
        [NSThread sleepForTimeInterval:2];
        
        NSLog(@"并行隊(duì)列任務(wù)二快結(jié)束:%@",[NSThread currentThread]);
        
    });
    dispatch_group_notify(group, conCurrentQueue, ^{
       
        NSLog(@"被通知的并行隊(duì)列任務(wù)三");
    });  
//結(jié)果時(shí)“被通知的并行隊(duì)列任務(wù)三”是在所有任務(wù)都執(zhí)行完成后才執(zhí)行
  • dispatch_group_wait

1.為先前提交的塊對(duì)象同步地等待完成;如果在指定的超時(shí)時(shí)間結(jié)束之前塊沒(méi)有完成,則返回
2.同步等待會(huì)阻塞線程,跟dispatch_block_wait原理一樣

dispatch_queue_t conCurrentQueue =  dispatch_queue_create("conCurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, conCurrentQueue, ^{
        NSLog(@"任務(wù)一開(kāi)始");
        [NSThread sleepForTimeInterval:2];
        
        NSLog(@"任務(wù)一快結(jié)束");
    });
    dispatch_group_async(group, conCurrentQueue, ^{
        NSLog(@"任務(wù)二開(kāi)始");
        [NSThread sleepForTimeInterval:6];
        
        NSLog(@"任務(wù)二快結(jié)束");
    });
    
    dispatch_time_t time=dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC));
    long result=dispatch_group_wait(group, time);
    if (result==0) {
        NSLog(@"組的block全部執(zhí)行完成");
    }
    else{
        NSLog(@"組的block沒(méi)有全部執(zhí)行完成,是timeout返回");
    }
    NSLog(@"-----------");
  • dispatch_group_enter

1.用這個(gè)方法指定一個(gè)操作將要加到group中,用來(lái)替代dispatch_group_async,注意它只能和dispatch_group_leave配對(duì)使用.
2.這種方式比dispatch_group_async更加靈活.比如我們可以在任務(wù)的完成回調(diào)里面寫dispatch_group_leave()

dispatch_queue_t conCurrentQueue =  dispatch_queue_create("conCurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"任務(wù)一開(kāi)始");
        [NSThread sleepForTimeInterval:2];
        
        NSLog(@"任務(wù)一快結(jié)束");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"任務(wù)二開(kāi)始");
        [NSThread sleepForTimeInterval:2];
        
        NSLog(@"任務(wù)二快結(jié)束");
        dispatch_group_leave(group);
    });
    
    dispatch_group_notify(group, conCurrentQueue, ^{
        NSLog(@"被通知任務(wù)開(kāi)始");
    });
    NSLog(@"-----");
  • Using Dispatch Semaphores(利用調(diào)度信號(hào)量)

關(guān)于信號(hào)量的解釋,借別人的一個(gè)例子:
停車場(chǎng)剩余4個(gè)車位,那么即使同時(shí)來(lái)了四輛車也能停的下。如果此時(shí)來(lái)了五輛車,那么就有一輛需要等待。信號(hào)量的值就相當(dāng)于剩余車位的數(shù)目,dispatch_semaphore_wait函數(shù)就相當(dāng)于來(lái)了一輛車,dispatch_semaphore_signal。就相當(dāng)于走了一輛車。停車位的剩余數(shù)目在初始化的時(shí)候就已經(jīng)指明了(dispatch_semaphore_create(value:Int))),調(diào)用一次dispatch_semaphore_signal,剩余的車位就增加一個(gè);調(diào)用一次dispatch_semaphore_wait剩余車位就減少一個(gè);當(dāng)剩余車位為0時(shí),再來(lái)車(即調(diào)用dispatch_semaphore_wait)就只能等待。有可能同時(shí)有幾輛車等待一個(gè)停車位。有些車主。沒(méi)有耐心,給自己設(shè)定了一段等待時(shí)間,這段時(shí)間內(nèi)等不到停車位就走了,如果等到了就開(kāi)進(jìn)去停車。而有些車主就像把車停在這,所以就一直等下去

  • dispatch_semaphore_create
  1. 該函數(shù)使用一個(gè)初始值創(chuàng)建一個(gè)dispatch_semaphore_t類型的信號(hào)量,注意:這里的傳入的參數(shù)value必須大于或等于0,否則dispatch_semaphore_create會(huì)返回NULL
    2.參數(shù)就是信號(hào)量的初始值
  • dispatch_semaphore_wait

1.等待信號(hào)量,該函數(shù)會(huì)使傳入的信號(hào)量dsema的值減1
2.函數(shù)的作用:如果dsema信號(hào)量的值大于0,該函數(shù)所處線程就繼續(xù)執(zhí)行下面的語(yǔ)句,并且將信號(hào)量的值減1;如果desema的值為0,那么這個(gè)函數(shù)就阻塞當(dāng)前線程等待timeout(注意timeout的類型為dispatch_time_t,需要傳入對(duì)應(yīng)的類型參數(shù)),如果等待的期間desema的值被dispatch_semaphore_signal函數(shù)加1了,且該函數(shù)(即dispatch_semaphore_wait)所處線程獲得了信號(hào)量,那么就繼續(xù)向下執(zhí)行并將信號(hào)量減1, 如果等待期間沒(méi)有獲取到信號(hào)量或者信號(hào)量的值一直為0,那么等到timeout時(shí),其所處線程自動(dòng)執(zhí)行其后語(yǔ)句。

  • dispatch_semaphore_signal

1.當(dāng)返回值為0時(shí)表示當(dāng)前并沒(méi)有線程等待其處理的信號(hào)量,其處理的信號(hào)量的值加1即可。當(dāng)返回值不為0時(shí),表示其當(dāng)前有(一個(gè)或多個(gè))線程等待其處理的信號(hào)量,并且該函數(shù)喚醒了一個(gè)等待的線程(當(dāng)線程有優(yōu)先級(jí)時(shí),喚醒優(yōu)先級(jí)最高的線程;否則隨機(jī)喚醒.

  • 關(guān)于信號(hào)量的用途和總結(jié)

0.注意,正常的使用順序是先降低然后再提高,這兩個(gè)dispatch_semaphore_wait 和dispatch_semaphore_signal函數(shù)通常成對(duì)使用
1.如果初始化信號(hào)量為1的話,相當(dāng)于給線程加鎖,因?yàn)樾盘?hào)量為1,不管什么情況下,都會(huì)保證只有一個(gè)線程再訪問(wèn)此關(guān)鍵代碼,是線程安全
2.可以相當(dāng)于設(shè)置最大并發(fā)數(shù)量,比如初始化的信號(hào)量為4,就算有五個(gè)線程來(lái)了,最多的情況也只會(huì)有四個(gè)同時(shí)進(jìn)行
3.加鎖


WechatIMG1.jpeg

如上所示,crash的原因翻譯過(guò)來(lái)是:就是說(shuō)你malloc分配的內(nèi)存賦值給了一個(gè)已經(jīng)被釋放的指針(此指針已不存在),其實(shí)我暫時(shí)不明白為什么會(huì)這樣報(bào)錯(cuò),我的理解是也是因?yàn)槎嗑€程同時(shí)寫數(shù)組的的問(wèn)題
修改成如下就行

dispatch_queue_t myQueue = dispatch_queue_create("MyQueue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    NSMutableArray * array = [[NSMutableArray alloc] init];
    for (int i =1; i<100; i++) {
        dispatch_async(myQueue, ^{
           
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            [array addObject:[NSString stringWithFormat:@"%d",i]];
            dispatch_semaphore_signal(semaphore);
        });
    }

4.設(shè)置多線程最大并發(fā)數(shù)

//crate的value表示,最多幾個(gè)資源可訪問(wèn)
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //任務(wù)1
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 1");
        sleep(1);
        NSLog(@"complete task 1");
        dispatch_semaphore_signal(semaphore);
    });
    //任務(wù)2
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 2");
        sleep(1);
        NSLog(@"complete task 2");
        dispatch_semaphore_signal(semaphore);
    });
    //任務(wù)3
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 3");
        sleep(1);
        NSLog(@"complete task 3");
        dispatch_semaphore_signal(semaphore);
    });
    /*
     2017-07-07 17:07:41.632 多線程-GCD[1125:163408] run task 1
     2017-07-07 17:07:41.632 多線程-GCD[1125:163421] run task 2
     2017-07-07 17:07:42.634 多線程-GCD[1125:163408] complete task 1
     2017-07-07 17:07:42.635 多線程-GCD[1125:163421] complete task 2
     2017-07-07 17:07:42.635 多線程-GCD[1125:163405] run task 3
     2017-07-07 17:07:43.640 多線程-GCD[1125:163405] complete task 3
     
     總結(jié):由于設(shè)定的信號(hào)值為2,先執(zhí)行兩個(gè)線程,等執(zhí)行完一個(gè),才會(huì)繼續(xù)執(zhí)行下一個(gè),保證同一時(shí)間執(zhí)行的線程數(shù)不超過(guò)2
     這也相當(dāng)于設(shè)置了多線程的最大并發(fā)數(shù)
     */
  • Using Dispatch Barriers(柵欄)

對(duì)于柵欄的理解:假設(shè)我們?cè)扔?0個(gè)任務(wù)要執(zhí)行,我們現(xiàn)在要插入一個(gè)任務(wù)5,這個(gè)任務(wù)5要在1,2,3,4,都并發(fā)執(zhí)行完了之后才能執(zhí)行,而6,7,8,9,10號(hào)任務(wù)要在這個(gè)任務(wù)5結(jié)束后才允許并發(fā)。這是就需要用到Barriers,當(dāng)然group也可以實(shí)現(xiàn),但是這個(gè)方法更好,關(guān)于柵欄的只能是同一個(gè)隊(duì)列,而group 可以是不同隊(duì)列,柵欄最好別用系統(tǒng)的全部隊(duì)列而是使用自己的全部隊(duì)列

  • dispatch_barrier_async

1.提交異步執(zhí)行的障礙塊并立即返回,不會(huì)阻塞線程
2.該方法的功能跟dispatch_async類似

  • dispatch_barrier_async_f

1.跟dispatch_barrier_async方法一樣,只會(huì)提交的是c函數(shù)

  • dispatch_barrier_sync

1.提交一個(gè)用于執(zhí)行的屏障塊對(duì)象,并等待該塊完成
2.該方法功能跟dispatch_sync類似

  • dispatch_barrier_sync_f

1.跟dispatch_barrier_async方法一樣,只會(huì)提交的是c函數(shù)

  • Managing Dispatch Sources

這個(gè)管理類對(duì)于我而言還是很少用到的,不過(guò)有個(gè)確實(shí)經(jīng)常用到的就是 time

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 3.1 Grand Central Dispatch(GCD)概要 3.1.1 什么是CGD Grand Cent...
    SkyMing一C閱讀 1,776評(píng)論 0 22
  • 同步/異步 同步:多個(gè)任務(wù)情況下,一個(gè)任務(wù)A執(zhí)行結(jié)束,才可以執(zhí)行另一個(gè)任務(wù)B。只存在一個(gè)線程也就是主線程。 異步:...
    XLsn0w閱讀 335評(píng)論 0 0
  • 在向隊(duì)列中添加任務(wù)時(shí),可以直接在對(duì)應(yīng)的函數(shù)中添加 block。但是如果想對(duì)任務(wù)進(jìn)行操作,比如監(jiān)聽(tīng)任務(wù)、取消任務(wù),就...
    fuyoufang閱讀 9,098評(píng)論 3 23
  • “橘子,身邊的人和事時(shí)刻提醒著我,我就是多余的。你有過(guò)這種感覺(jué)嗎?” 距離看到這條信息已經(jīng)過(guò)去一個(gè)小時(shí)了,我呆呆的...
    橘子姑娘_閱讀 225評(píng)論 8 2
  • 答陸原靜書(二) 答“養(yǎng)生以靜心寡欲為要……愈不可矣”句; 學(xué)到現(xiàn)在,對(duì)于“純乎天理”有一些感覺(jué),天理是本身...
    偶爾閑情閱讀 386評(píng)論 0 1

友情鏈接更多精彩內(nèi)容