一、GCD
1、同步/異步 和 串行/併發
1)、GCD調用的四種組合
dispatch_sync(serial_queue,^{…}); 同步調用串行隊列
dispatch_async(serial_queue,^{…});異步調用串行隊列
dispatch_sync(concurrent_queue,^{…});
dispatch_async(concurrent_queue,^{…});
2)、dispatch_sync(serial_queue,^{…}); 同步調用串行隊列
回答出死鎖的6分,還要回答出爲什麼死鎖才能滿分。死鎖原因如下:
3)、dispatch_async(serial_queue,^{…});異步調用串行隊列
下面代碼不會像同步串行一樣產生死鎖。
4)、dispatch_async(concurrent_queue,^{…});異步併發
爲什麼printLog函數不執行呢?因爲不管GCD通過哪個隊列執行,最終都會在底層的線程中執行,但是底層線程默認沒有開啓runLoop,所以perform函數不執行。
2、dispatch_barrier_async
1)、怎樣通過GCD實現多讀單寫?
dispatch_barrier_async(concurrent_queue,^{//寫操作})
讀操作爲什麼不用異步呢?因爲讀操作需要立即返回結果。而併發隊列保證了多個線程可以併發執行。
3、dispatch_group相關知識點
1)、使用GCD實現這個需求?A、B、C三個任務併發,完成後執行任務D?
我認爲作者的講解是錯的,作者的代碼只能保證block執行完成後開始執行D操作,並不能保證圖片都下載成功後去執行D操作。
二、NSOperation
1、主要優點
a、可以添加任務依賴
b、可以控制任務執行狀態:isReady、isExecuting、isFinished、isCancelled。如果只重寫了main方法,則系統會控制任務執行狀態的變化以及任務的退出。如果重寫了start方法,則需要自行控制任務狀態。
c、可以控制最大併發量
2、oc源碼說明系統如何控制任務狀態
該處源碼解讀基於gnustep-base-1.24.9版本
_finish方法的實現如下:
3、系統怎樣移除一個isFinished=YES的NSOperation的?===網上再搜搜,印證一下!
任務完成後_finish方法通過KVO的方式變更finished狀態爲YES,系通過通過NSOperation Queue來監聽該KVO,然後在合適的時機移除該NSOperation對象。
三、NSThread
NSThread相關的面試問題往往是結合RunLoop來考察的。
1、NSThread的啓動流程
2、NSThread實現的常駐線程
比着上圖,只是在爲NSThread指定的selector中啓動RunLoop,如下圖
3、NSThread的實現機制,即start方法的解讀
該處源碼解讀基於gnustep-base-1.24.9版本。
線程的啓動函數nsthreadLauncher源碼如下:
線程的main函數源碼如下:
start方法開始做了一些異常的判斷,經歷了這些異常判斷之後,在1201行調用pthread_create函數來創建線程,然後在該函數中調用線程的啓動函數nsthreadLauncher,nsthreadLauncher函數中調用線程的main函數,main函數調用創建線程時傳進來的selector,如果要實現常駐線程,則在selector中調起RunLoop。
四、多線程與鎖
1、iOS中有哪些常用鎖?
a、@synchronized:一般在創建單例對象的時候使用。
b、atomic:修飾屬性的關鍵字;對被修飾對象進行原子操作(不負責使用)
c、OSSpinLock:自旋鎖,循環等待訪問,不釋放當前資源==對這個解釋我不理解,再搜搜??用於輕量級數據訪問,如簡單的int值+1/-1操作。
d、NSRecursiveLock:遞歸鎖,特點是可以重入。
e、NSLock:一般用於線程同步。
這個情況可以通過換成遞歸鎖解決。
f、dispatch_semaphore_t:信號量
2、dispatch_semaphore_t講解
1)、dispatch_semaphore_t常用函數
dispatch_semaphore_create(int value)創建數值爲value的信號量;
dispatch_semaphore_wait(semaphore,time)設置當前線程對信號量的等待時間(如DISPATCH_TIME_FOREVER代表永遠),如果沒有資源則等待;
dispatch_semaphore_singal(semaphore)釋放信號量的一個值;
2)、dispatch_semaphore_create()函數
該函數主要用於創建semaphore結構,semaphore結構定義如下:struct semaphore{int value; List<thread>;}其中value是信號量的值,List存儲被阻塞的線程的唯一標識,如pid。
3)、dispatch_semaphore_wait()函數
函數主要實現如圖,途中第二句代碼的意思是如果信號量的值小於0,則調用該函數的線程主動的將自己阻塞起來。
4)、dispatch_semaphore_singal()函數
函數主要實現如圖,途中第二句代碼的意思是如果信號量的值小於等於0,則說明有線程處於阻塞狀態,通過wakeup函數去喚醒阻塞的線程。喚醒是一個被動實現。
3、iOS系統爲我們提供的幾種多線程技術各自的特點是怎樣的?
1)、GCD用來實現一些簡單的線程同步,包括一些子線程的分派,包括實現一些類似於多讀單寫這種場景的問題
2)、NSOperation和NSOperation Queue由於可以控制任務狀態、依賴,所以AFNetwork和SDWebImage內部都使用者兩個類實現多線程。
3)、NSThread常用於實現常駐線程。GCD和NSOperation都不能實現常駐線程,因爲他們底層都是通過系統的線程池執行任務。