知識小總結(jié)一 (多線程)??

線程與多線程相關(guān)概念


進(jìn)程

  • 資源分配的最小獨立單元,進(jìn)程是具有一定獨立功能的程序關(guān)于某個數(shù)據(jù)集合上的一次運行活動,進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個獨立單位

線程

  • 進(jìn)程下的一個分支,是進(jìn)程的實體,是CPU調(diào)度和分派的基本單元,它是比進(jìn)程更小的能獨立運行的基本單位,線程自己基本不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(程序計數(shù)器、一組寄存器、棧),但是它可與同屬一個進(jìn)程的其他線程共享進(jìn)程所擁有的全部資源。

進(jìn)程和線程的主要差別

  • 在于它們是不同的操作系統(tǒng)資源管理方式。進(jìn)程有獨立的地址空間,一個進(jìn)程崩潰后,在保護(hù)模式下不會對其它進(jìn)程產(chǎn)生影響,而線程只是一個進(jìn)程中的不同執(zhí)行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等于整個進(jìn)程死掉,所以多進(jìn)程的程序要比多線程的程序健壯,但在進(jìn)程切換時,耗費資源較大,效率要差一些。

重要概念(非常非常重要,不能理解這些概念多線程這輩子也學(xué)不會)

  • 任務(wù):即操作,你想要干什么,說白了就是一段代碼,在 GCD 中就是一個 Block

  • 隊列:用于存放任務(wù)

  • 同步和異步:同步異步概念面向的是任務(wù)。同步指第一個任務(wù)不執(zhí)行完,不會開始第二個,異步是不管第一個有沒有執(zhí)行完,都開始第二個。

  • 串行和并行:串行并行概念面向的是隊列。串行是多個任務(wù)按一定順序執(zhí)行,并行是多個任務(wù)同時執(zhí)行


iOS中隊列的種類有

  • 串行隊列:隊列中的任務(wù)只會順序執(zhí)行
  • 并行隊列: 隊列中的任務(wù)通常會并發(fā)執(zhí)行
  • 主隊列:每一個應(yīng)用程序?qū)?yīng)唯一主隊列,直接GET即可;在多線程開發(fā)中,使用主隊列更新UI
  • 全局隊列:是系統(tǒng)的,直接拿過來(GET)用就可以;與并行隊列類似

iOS中常用的多線程技術(shù)

pthread "已被拋棄"
NSThread
NSOperation
GCD

NSThread

  • NSThread是OC語言面向?qū)ο蟮亩嗑€程方案。所以你可以直接操控線程對象,非常直觀和方便。但是,它的生命周期還是需要我們手動管理,所以這套方案只有在一些非常簡單的場景才會用

  • 創(chuàng)建并自動啟動

[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:nil];```

- 獲取當(dāng)前線程
```swift
[NSThread currentThread];```

- 獲取主線程
```swift
[NSThread mainThread];```


----

####GCD

- GCD(Grand Central Dispatch)是基于C語言開發(fā)的一套多線程開發(fā)機(jī)制,也是目前蘋果官方推薦的多線程開發(fā)方法。它會自動合理地利用更多的CPU內(nèi)核(比如雙核、四核),最重要的是它會自動管理線程的生命周期(創(chuàng)建線程、調(diào)度任務(wù)、銷毀線程),完全不需要我們管理,我們只需要告訴干什么就行。

####隊列

- 獲取主隊列

dispatch_queue_t queue = dispatch_get_main_queue();```

  • 獲取全局并行隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);```

----
####創(chuàng)建隊列

- 創(chuàng)建串行隊列 

dispatch_queue_t queue = dispatch_queue_create("testQueue", NULL);```

  • 創(chuàng)建并行隊列
dispatch_queue_t queue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_CONCURRENT);```

####任務(wù)
- 創(chuàng)建同步任務(wù)

dispatch_sync(queue1, ^{

});```

  • 創(chuàng)建異步任務(wù)
dispatch_async(queue2, ^{

  });```

----

####隊列組

- 隊列組可以將很多隊列添加到一個組里,這樣做的好處是,當(dāng)這個組里所有的任務(wù)都執(zhí)行完了,隊列組會通過一個方法通知我們

1、創(chuàng)建隊列組
dispatch_group_t group = dispatch_group_create();
2、創(chuàng)建隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
3、使用隊列組的方法執(zhí)行任務(wù)
dispatch_group_async(group, queue, ^{

});
4、當(dāng)隊列組的方法全部執(zhí)行完后,會執(zhí)行
dispatch_group_notify(group, dispatch_get_main_queue(), ^{

});```


線程死鎖

  • 簡單的說,就是在當(dāng)前串行隊列中添加一個同步任務(wù),因為隊列是串行的只能一個一個的執(zhí)行任務(wù),而同步任務(wù)會阻塞隊列,這樣必須等該同步任務(wù)執(zhí)行完才能執(zhí)行其他任務(wù),但是該同步任務(wù)又是其他任務(wù)的一部分,所以兩個任務(wù)互相等待一直阻塞隊列,這就是線程死鎖。

NSOperation

  • NSOperation 是蘋果公司對 GCD 的封裝,完全面向?qū)ο螅允褂闷饋砀美斫狻?大家可以看到 NSOperation 和 NSOperationQueue 分別對應(yīng) GCD 的 任務(wù) 和 隊列 。

  • 任務(wù)
    NSOperation 只是一個抽象類,所以不能封裝任務(wù)。但它有 2 個子類用于封裝任務(wù)。分別是:NSInvocationOperationNSBlockOperation。創(chuàng)建一個 Operation 后,需要調(diào)用 start 方法來啟動任務(wù),它會默認(rèn)在當(dāng)前隊列同步執(zhí)行。

  • 通過NSInvocationOperation創(chuàng)建任務(wù)

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];```


- 通過NSBlockOperation創(chuàng)建任務(wù)

NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{

}];```

  • NSBlockOperation 還有一個方法:addExecutionBlock:,通過這個方法可以給 Operation 添加多個執(zhí)行 Block

隊列

獲取主隊列
NSOperationQueue *queue = [NSOperationQueue mainQueue];
創(chuàng)建其他隊列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
往隊列中添加任務(wù)
[queue addOperation:operation];
NSOperationQueue有一個屬性maxConcurrentOperationCount代表最大并發(fā)數(shù),用來設(shè)置最多可以讓多少個任務(wù)同時執(zhí)行。當(dāng)設(shè)置為 1 的時候,就是串行隊列。```

----

####線程依賴

- NSOperation 有一個非常實用的功能,那就是添加依賴。比如有 3 個任務(wù):A: 從服務(wù)器上下載一張圖片,B:給這張圖片加個水印,C:把圖片返回給服務(wù)器。

- 這時就可以用到依賴了

[operation2 addDependency:operation1];
[operation3 addDependency:operation2];
[queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:NO];```

  • 返回主線程的方法
NSThread
[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:NO];

GCD

dispatch_async(dispatch_get_main_queue(), ^{

});```


####NSOperation

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

}];```

線程同步

  • 所謂線程同步就是為了防止多個線程搶奪同一個資源造成的數(shù)據(jù)安全問題,所采取的一種措施。

  • 互斥鎖 :給需要同步的代碼塊加一個互斥鎖,就可以保證每次只有一個線程訪問此代碼塊。

@synchronized(self) {
    //需要執(zhí)行的代碼塊
}```

- 同步執(zhí)行 :我們可以把多個線程都要執(zhí)行此段代碼添加到同一個串行隊列,這樣就實現(xiàn)了線程同步的概念。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容