日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS开发-10.多线程

發(fā)布時間:2024/1/1 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS开发-10.多线程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
  • 1.iOS中的常見多線程方案
a) NSThread / GCD / NSOperation底層都是pthreadb) NSThread開啟線程方式1) 動態(tài)實例化 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test:) object:nil]; thread.threadPriority = 1; //設(shè)置線程的優(yōu)先級(0.0 - 1.0, 1.0最高級) [thread start]; 2) 靜態(tài)實例化 [NSThread detachNewThreadSelector:@selector(test:) toTarget:self withObject:nil]; 3) 隱式實例化3.1) [self performSelectorOnMainThread:@selector(test:) withObject:nil waitUntilDone:YES];
  • 2.GCD的常用函數(shù)
a) GCD中有2個用來執(zhí)行任務(wù)的函數(shù)1) 用同步的方式執(zhí)行任務(wù)dispatch_sync(dispatch_queue_t queue, dispatch_block_t block); // queue:隊列 block:任務(wù)1.1) dispatch_sync : 立馬在當(dāng)前線程同步執(zhí)行任務(wù),不執(zhí)行就不會往下走2) 用異步的方式執(zhí)行任務(wù)dispatch_async(dispatch_queue_t queue, dispatch_block_t block);2.1) dispatch_async : 不要求立馬在當(dāng)前線程同步執(zhí)行任務(wù),等上一個任務(wù)(也可能是整個外部的大函數(shù)執(zhí)行完畢)執(zhí)行完了再執(zhí)行b) GCD源碼https://github.com/apple/swift-corelibs-libdispatch
  • 3.GCD的隊列
a) GCD的隊列可以分為2大類型1) 并發(fā)隊列(Concurrent Dispatch Queue)1.1) 可以讓多個任務(wù)并發(fā)(同時)執(zhí)行(自動開啟多個線程同時執(zhí)行任務(wù))1.2) 并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效b) 串行隊列(Serial Dispatch Queue)1) 讓任務(wù)一個接著一個地執(zhí)行(一個任務(wù)執(zhí)行完畢后,再執(zhí)行下一個任務(wù))2) 主隊列是一種特殊的串行隊列c) 隊列的特點 : 排隊,FIFO,First In First Out 先進先出d) Global Queue全局隊列的指針地址是相同的,而手動創(chuàng)建的隊列則地址是不相同的
  • 4.容易混淆的術(shù)語
a) 同步和異步主要影響:能不能開啟新的線程1) 同步:在當(dāng)前線程中執(zhí)行任務(wù),不具備開啟新線程的能力2) 異步:在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力b) 并發(fā)和串行主要影響:任務(wù)的執(zhí)行方式1) 并發(fā):多個任務(wù)并發(fā)(同時)執(zhí)行2) 串行:一個任務(wù)執(zhí)行完畢后,再執(zhí)行下一個任務(wù)
  • 5.各種隊列的執(zhí)行效果
a) 使用sync函數(shù)往當(dāng)前串行隊列中添加任務(wù),會卡住當(dāng)前的串行隊列(產(chǎn)生死鎖)b) performSelector:withObject:afterDelay: 1) 有afterDelay的方法都是跟Runloop有關(guān),相當(dāng)于添加了一個定時器到Runloop去執(zhí)行 所以你要看當(dāng)前執(zhí)行任務(wù)的線程有沒有Runloop2) 在主線程好時正常調(diào)用,但是會延遲,因為主線程默認(rèn)就會開啟一個Runloop,延遲是因為主線程的任務(wù)執(zhí)行順序是串行的,需要等上一個任務(wù)執(zhí)行完畢,可以理解為包裝該線程調(diào)用的{}范圍函數(shù)調(diào)用完畢,例如viewDidLoad方法調(diào)用完畢3) 但是在子線程卻不好使,直接不調(diào)用,因為子線程沒有開啟Runloop來保活
  • 6.隊列組的使用
a) 思考:如何用gcd實現(xiàn)以下功能1) 異步并發(fā)執(zhí)行任務(wù)1、任務(wù)22) 等任務(wù)1、任務(wù)2都執(zhí)行完畢后,再回到主線程執(zhí)行任務(wù)3

  • 7.多線程的安全隱患
a) 資源共享1) 1塊資源可能會被多個線程共享,也就是多個線程可能會訪問同一塊資源2) 比如多個線程訪問同一個對象、同一個變量、同一個文件b) 當(dāng)多個線程訪問同一塊資源時,很容易引發(fā)數(shù)據(jù)錯亂和數(shù)據(jù)安全問題c) 多線程安全隱患示例01 – 存錢取錢

d) 多線程安全隱患示例02 – 賣票

e) 多線程安全隱患分析

f) 多線程安全隱患的解決方案1) 解決方案:使用線程同步技術(shù)(同步,就是協(xié)同步調(diào),按預(yù)定的先后次序進行)2) 線程同步本質(zhì):是不能同時讓多條線程占用一個資源2) 常見的線程同步技術(shù)是:加鎖(所有線程都用同一把鎖)3) 鎖的原理:首先判斷這把鎖有沒有被人加過,沒有就會加鎖,有被加過,就會等待

  • 8.iOS中的線程同步方案
a) OSSpinLock(High-level-lock高級鎖)1) OSSpinLock叫做”自旋鎖”,等待鎖的線程會處于忙等(busy-wait)狀態(tài)(相當(dāng)于執(zhí)行了一個do while循環(huán))一直占用著CPU資源2) iOS10.0開始不推薦使用,目前已經(jīng)不再安全,可能會出現(xiàn)優(yōu)先級反轉(zhuǎn)問題(如果等待鎖的線程優(yōu)先級較高,它會一直占用著CPU資源,優(yōu)先級低的線程就無法釋放鎖,造成死鎖的現(xiàn)象)3) 需要導(dǎo)入頭文件#import <libkern/OSAtomic.h>

b) os_unfair_lock(Low-level-lock低級鎖)1) os_unfair_lock用于取代不安全的OSSpinLock ,從iOS10開始才支持2) 從底層調(diào)用看,等待os_unfair_lock鎖的線程會處于休眠狀態(tài),并非忙等3) 需要導(dǎo)入頭文件#import <os/lock.h>

c) pthread_mutex(Low-level-lock低級鎖)1) mutex叫做”互斥鎖”,等待鎖的線程會處于休眠狀態(tài)2) 需要導(dǎo)入頭文件#import <pthread.h>

3) pthread_mutex – 遞歸鎖3.1) 遞歸鎖:允許用同一條線程對一把鎖進行重復(fù)加鎖

4) pthread_mutex – 條件4.1) 條件(等待條件,等不到條件就休眠,等待的時候解鎖,喚醒的時候加鎖,次數(shù)對等,一般用于線程之間的通信)

d) NSLock1) NSLock是對mutex普通鎖的封裝

e) NSRecursiveLock1) NSRecursiveLock是對mutex遞歸鎖的封裝,API跟NSLock基本一致 f) NSCondition1) NSCondition是對mutex和cond的封裝2) signal:信號發(fā)出的時機,決定了后續(xù)代碼的執(zhí)行,因為在解鎖前和解鎖后3) signal:信號(單個)和broadcast:廣播(多個)的區(qū)別

g) NSConditionLock1) NSConditionLock是對NSCondition的進一步封裝,可以設(shè)置具體的條件值2) 初始化不設(shè)置條件值的時候,默認(rèn)條件值就是03) lock:直接加鎖,不等條件值,如果沒有加鎖,那就加鎖4) lockWhenCondition:條件值為多少的時候才加鎖5) unlockWithCondition:解鎖并且設(shè)置條件值6) 在子線程執(zhí)行的任務(wù),可以達(dá)到依賴的效果

h) dispatch_semaphore1) semaphore叫做”信號量”2) 信號量的初始值,可以用來控制線程并發(fā)訪問的最大數(shù)量3) 信號量的初始值為1,代表同時只允許1條線程訪問資源,保證線程同步

i) dispatch_queue1) 直接使用GCD的串行隊列,也是可以實現(xiàn)線程同步的2) 不是說有多線程就需要加鎖

j) @synchronized1) @synchronized是對mutex遞歸鎖的封裝2) 源碼查看:objc4中的objc-sync.mm文件3) @synchronized(obj)內(nèi)部會生成obj對應(yīng)的遞歸鎖,然后進行加鎖、解鎖操作4) 性能比較差,蘋果官方不推薦使用,所以代碼提示也沒有

  • 9.iOS線程同步方案性能比較

  • 10.自旋鎖、互斥鎖比較

a) 什么情況使用自旋鎖比較劃算?1) 預(yù)計線程等待鎖的時間很短2) 加鎖的代碼(臨界區(qū))經(jīng)常被調(diào)用,但競爭情況很少發(fā)生3) CPU資源不緊張4) 多核處理器b) 什么情況使用互斥鎖比較劃算?1) 預(yù)計線程等待鎖的時間較長2) 臨界區(qū)有IO操作3) 臨界區(qū)代碼復(fù)雜或者循環(huán)量大4) 臨界區(qū)競爭非常激烈5) 單核處理器c) 臨界區(qū):lock與unlock之間的代碼 d) IO操作:文件操作(讀和寫的操作)
  • 11.atomic
a) atomic用于保證屬性setter、getter的原子性操作,相當(dāng)于在getter和setter內(nèi)部加了線程同步的鎖b) 可以參考源碼objc4的objc-accessors.mmc) 它并不能保證使用屬性的過程是線程安全的
  • 12.iOS中的讀寫安全方案
a) 思考如何實現(xiàn)以下場景1) 同一時間,只能有1個線程進行寫的操作2) 同一時間,允許有多個線程進行讀的操作3) 同一時間,不允許既有寫的操作,又有讀的操作b) 上面的場景就是典型的“多讀單寫”,經(jīng)常用于文件等數(shù)據(jù)的讀寫操作c) iOS中的實現(xiàn)方案有1) pthread_rwlock:讀寫鎖

2) dispatch_barrier_async:異步柵欄調(diào)用2.1) 這個函數(shù)傳入的并發(fā)隊列必須是自己通過dispatch_queue_cretate創(chuàng)建的2.2) 如果傳入的是一個串行或是一個全局的并發(fā)隊列,那這個函數(shù)便等同于dispatch_async函數(shù)的效果

  • 13.GNUstep
a) GNUstep是GNU計劃的項目之一,它將Cocoa的OC庫重新開源實現(xiàn)了一遍b) 源碼地址:http://www.gnustep.org/resources/downloads.phpc) 雖然GNUstep不是蘋果官方源碼,但還是具有一定的參考價值
  • 14.其它知識點總結(jié)
a) lldb查看匯編指令級別代碼時一行一行的運行 1) stepi(si)2) nexti(ni):也是一行一行,但是遇到函數(shù)調(diào)用會一筆帶過這個函數(shù)調(diào)用3) c:直接跳到下一個斷點b) 定義變量的時候同時給他賦值結(jié)構(gòu)體可以這么干,但是不能直接給結(jié)構(gòu)體賦值c) 線程的任務(wù)一旦執(zhí)行完畢,生命周期就結(jié)束了,無法再使用 // 準(zhǔn)確來講,使用runloop是為了讓線程保持激活狀態(tài)

總結(jié)

以上是生活随笔為你收集整理的iOS开发-10.多线程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。