iOS-多線程

1、問題:執(zhí)行任務(wù)1、2;再執(zhí)行3、4有哪些方法?

  1. dispatch_barrier_ 阻塞隊(duì)列
    使用dispatch_barrier_ 的時(shí),要主要兩點(diǎn)一點(diǎn)隊(duì)列必須是自定義的隊(duì)列,并且是并發(fā)隊(duì)列;dispatch_get_global(0,0)不行
dispatch_queue_t  myQueue = dispatch_queue_create("myqueue",DISPATCH_QUEUE_CONCURRENT);
   
    NSLog(@"先頭任務(wù)");
    dispatch_async(myQueue,^{
        NSLog(@"當(dāng)前線程%p==任務(wù)1",[NSThread currentThread]);
    });

    dispatch_async(myQueue,^{
        NSLog(@"當(dāng)前線程%p==任務(wù)2",[NSThread currentThread]);
    });

    NSLog(@"pre barrier");
    dispatch_barrier_async(myQueue, ^{
        NSLog(@"當(dāng)前線程%p==阻塞隊(duì)列myQueue",[NSThread currentThread]);
    });
    NSLog(@"后續(xù)任務(wù)");
    dispatch_async(myQueue,^{
        NSLog(@"當(dāng)前線程%p==任務(wù)3",[NSThread currentThread]);
    });

    dispatch_async(myQueue,^{
        NSLog(@"當(dāng)前線程%p==任務(wù)4",[NSThread currentThread]);
    });

打印結(jié)果


image.png
dispatch_queue_t  myQueue = dispatch_queue_create("myqueue",DISPATCH_QUEUE_CONCURRENT);
   
    NSLog(@"先頭任務(wù)");
    dispatch_async(myQueue,^{
        NSLog(@"當(dāng)前線程%p==任務(wù)1",[NSThread currentThread]);
    });

    dispatch_async(myQueue,^{
        NSLog(@"當(dāng)前線程%p==任務(wù)2",[NSThread currentThread]);
    });

    NSLog(@"pre barrier");
    dispatch_barrier_sync(myQueue, ^{
        NSLog(@"當(dāng)前線程%p==阻塞隊(duì)列myQueue",[NSThread currentThread]);
    });
    NSLog(@"后續(xù)任務(wù)");
    dispatch_async(myQueue,^{
        NSLog(@"當(dāng)前線程%p==任務(wù)3",[NSThread currentThread]);
    });

    dispatch_async(myQueue,^{
        NSLog(@"當(dāng)前線程%p==任務(wù)4",[NSThread currentThread]);
    });

打印信息


image.png

dispatch_barrier_async不會(huì)阻塞當(dāng)前線程;
dispatch_barrier_sync會(huì)卡住當(dāng)前線程;

  1. diapatch_group_queue
1、dispatch_group_create創(chuàng)建一個(gè)調(diào)度任務(wù)組
2、dispatch_group_async 把一個(gè)任務(wù)異步提交到任務(wù)組里
3、dispatch_group_enter/dispatch_group_leave 這種方式用在不使用dispatch_group_async來提交任務(wù),且必須配合使用
4、dispatch_group_notify 用來監(jiān)聽任務(wù)組事件的執(zhí)行完畢
5、dispatch_group_wait 設(shè)置等待時(shí)間,在等待時(shí)間結(jié)束后,如果還沒有執(zhí)行完任務(wù)組,則返回。返回0代表執(zhí)行成功,非0則執(zhí)行失敗

場景1:

現(xiàn)在有4個(gè)任務(wù),任務(wù)1、任務(wù)2、任務(wù)3、任務(wù)4. 任務(wù)3必須在任務(wù)2之后,任務(wù)4必須在前3個(gè)任務(wù)都執(zhí)行完成后,才能執(zhí)行,并且需要在主線程更新UI。

思路分析:

任務(wù)3必須在任務(wù)2之后,所以這兩個(gè)必須串行執(zhí)行,同時(shí),任務(wù)2和3整體可以和任務(wù)1并行執(zhí)行,最后,任務(wù)4只能等待前3個(gè)任務(wù)全部執(zhí)行完成,才能執(zhí)行。這里就可以用group快速實(shí)現(xiàn)場景需求。

dispatch_queue_t  c_Queue = dispatch_queue_create("myqueue",DISPATCH_QUEUE_CONCURRENT);//并發(fā)隊(duì)列
    dispatch_queue_t  s_Queue = dispatch_queue_create("myqueue",DISPATCH_QUEUE_SERIAL);//串行隊(duì)列
    
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, c_Queue, ^{
        NSLog(@"任務(wù)1");
    });
   
    dispatch_group_async(group, s_Queue, ^{
        NSLog(@"任務(wù)2");
    });
    dispatch_group_async(group, s_Queue, ^{
        NSLog(@"任務(wù)3");
    });
    dispatch_group_async(group, dispatch_get_main_queue(), ^{
        NSLog(@"任務(wù)4");
    });
image.png

其中3始終在2的后面,1的位置始終在4前面,4在最后。

  1. dispatch_semaphore信號(hào)量:就是一種可用來控制訪問資源的數(shù)量的標(biāo)識(shí),設(shè)定了一個(gè)信號(hào)量,在線程訪問之前,加上信號(hào)量的處理,則可告知系統(tǒng)按照我們指定的信號(hào)量數(shù)量來執(zhí)行多個(gè)線程。

假設(shè)現(xiàn)在系統(tǒng)有兩個(gè)空閑資源可以被利用,但同一時(shí)間卻有三個(gè)線程要進(jìn)行訪問,這種情況下,該如何處理呢?

dispatch_semaphore_create(long value); // 創(chuàng)建信號(hào)量
dispatch_semaphore_signal(dispatch_semaphore_t deem); // 發(fā)送信號(hào)量
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout); // 等待信號(hào)量
// 創(chuàng)建信號(hào)量
    dispatch_semaphore_t sem = dispatch_semaphore_create(1);
    
    dispatch_queue_t  c_Queue = dispatch_queue_create("myqueue",DISPATCH_QUEUE_CONCURRENT);//并發(fā)隊(duì)列
    
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    dispatch_async(c_Queue, ^{
        sleep(1);
        NSLog(@"任務(wù)1");
    });
    
    dispatch_async(c_Queue, ^{
        NSLog(@"任務(wù)2");
        dispatch_semaphore_signal(sem);
    });
    
    // 等待信號(hào)量 超時(shí)時(shí)間  -1  sem 小于0就會(huì)阻塞
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    
    dispatch_async(c_Queue, ^{
        NSLog(@"任務(wù)3");
        dispatch_semaphore_signal(sem);
    });
  1. NSOperition
    NSOperation、NSOperationQueue 常用屬性和方法歸納
    1、NSOperation 常用屬性和方法
    取消操作方法
  • (void)cancel;可取消操作,實(shí)質(zhì)是標(biāo)記 isCancelled 狀態(tài)。
    判斷操作狀態(tài)方法
  • (BOOL)isFinished;判斷操作是否已經(jīng)結(jié)束。
  • (BOOL)isCancelled;判斷操作是否已經(jīng)標(biāo)記為取消。
  • (BOOL)isExecuting;判斷操作是否正在在運(yùn)行。
  • (BOOL)isReady;判斷操作是否處于準(zhǔn)備就緒狀態(tài),這個(gè)值和操作的依賴關(guān)系相關(guān)。
    操作同步
  • (void)waitUntilFinished;阻塞當(dāng)前線程,直到該操作結(jié)束。可用于線程執(zhí)行順序的同步。
  • (void)setCompletionBlock:(void (^)(void))block;completionBlock會(huì)在當(dāng)前操作執(zhí)行完畢時(shí)執(zhí)行 completionBlock。
  • (void)addDependency:(NSOperation *)op;添加依賴,使當(dāng)前操作依賴于操作 op 的完成。
  • (void)removeDependency:(NSOperation *)op;移除依賴,取消當(dāng)前操作對(duì)操作 op 的依賴。
    @property (readonly, copy) NSArray<NSOperation *> *dependencies;在當(dāng)前操作開始執(zhí)行之前完成執(zhí)行的所有操作對(duì)象數(shù)組。

2、NSOperationQueue常用屬性和方法
取消/暫停/恢復(fù)操作

  • (void)cancelAllOperations;可以取消隊(duì)列的所有操作。
  • (BOOL)isSuspended;判斷隊(duì)列是否處于暫停狀態(tài)。 YES 為暫停狀態(tài),NO 為恢復(fù)狀態(tài)。
  • (void)setSuspended:(BOOL)b;可設(shè)置操作的暫停和恢復(fù),YES 代表暫停隊(duì)列,NO 代表恢復(fù)隊(duì)列。
    操作同步
  • (void)waitUntilAllOperationsAreFinished;阻塞當(dāng)前線程,直到隊(duì)列中的操作全部執(zhí)行完畢。
    添加/獲取操作
  • (void)addOperationWithBlock:(void (^)(void))block;向隊(duì)列中添加一個(gè) NSBlockOperation 類型操作對(duì)象。
  • (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait;向隊(duì)列中添加操作數(shù)組,wait 標(biāo)志是否阻塞當(dāng)前線程直到所有操作結(jié)束
  • (NSArray *)operations;當(dāng)前在隊(duì)列中的操作數(shù)組(某個(gè)操作執(zhí)行結(jié)束后會(huì)自動(dòng)從這個(gè)數(shù)組清除)。
  • (NSUInteger)operationCount;當(dāng)前隊(duì)列中的操作數(shù)。
    獲取隊(duì)列
  • (id)currentQueue;獲取當(dāng)前隊(duì)列,如果當(dāng)前線程不是在 NSOperationQueue 上運(yùn)行則返回 nil。
  • (id)mainQueue;獲取主隊(duì)列。

不錯(cuò)的文章
https://blog.csdn.net/u011043997/article/details/86678771

?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 一 進(jìn)程和線程 進(jìn)程 進(jìn)程是一個(gè)具有一定獨(dú)立功能的程序關(guān)于某次數(shù)據(jù)集合的一次運(yùn)行活動(dòng),它是操作系統(tǒng)分配資源的基本單...
    丁勒個(gè)東閱讀 271評(píng)論 0 0
  • NSOperation 簡介 NSOperation 和 GCD 比較 NSInvocationOperation...
    我是誰重要嗎閱讀 295評(píng)論 0 0
  • 歡迎大家指出文章中需要改正或者需要補(bǔ)充的地方,我會(huì)及時(shí)更新,非常感謝。 一. 多線程基礎(chǔ) 1. 進(jìn)程 進(jìn)程是指在系...
    xx_cc閱讀 7,370評(píng)論 11 70
  • 單次函數(shù)dispatch_once 單次函數(shù)一般用來創(chuàng)建單例或者是執(zhí)行只需要執(zhí)行一次的程序。 dispatch_o...
    xxxxxxxx_123閱讀 407評(píng)論 0 0
  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友。感恩相遇!感恩不離不棄。 中午開了第一次的黨會(huì),身份的轉(zhuǎn)變要...
    余生動(dòng)聽閱讀 10,798評(píng)論 0 11

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