IOS執行緒介紹

weixin_33912445發表於2016-06-28

執行緒(Threads)

  • 1個程式(活在記憶體中)想要執行任務,必須要至少有一個執行緒
  • 一個程式所有任務都是線上程中執行的
  • 執行緒是程式中一個單一的順序控制流程。程式內一個相對獨立的、可排程的執行單元,是系統獨立排程和分派CPU的基本單位指執行中的程式的排程單位。在單個程式中同時執行多個執行緒完成不同的工作,稱為多執行緒。

執行緒的序列

  • 一個執行緒中任務的執行是序列的
  • 如果要在一個執行緒裡面執行多個任務,那麼只能一個一個按順序執行,一個時間內,1一個執行緒只能執行一個任務

多執行緒

  • 一個程式中開啟多個執行緒,每條執行緒同時(並行)執行不同任務

多執行緒的原理

  • 同一時間,cpu只能處理一條執行緒,只有一條執行緒在工作
  • 多執行緒並行,其實就是cpu快速的在多條執行緒之間排程切換
  • 如果cpu排程執行緒足夠快,就會造成多執行緒並行的假想

共享程式資源

  • 在同一程式中的各個執行緒,都可以共享該程式所擁有的資源,這首先表現在:所有執行緒都具有相同的地址空間(程式的地址空間),這意味著,執行緒可以訪問該地址空間的每一個虛地址;此外,還可以訪問程式所擁有的已開啟檔案、定時器、訊號量機構等。由於同一個程式內的執行緒共享記憶體和檔案,所以執行緒之間互相通訊不必呼叫核心。

優缺點

  • 優點:能適當提高程式的執行效率,能提高資源利用率
  • 缺點:建立執行緒是需要開銷的,ios下主要成本包括:核心資料結構(1kb),棧空間(子執行緒512kb,主執行緒1Mb,也可以用—setStackSize:設定,但是必須是4k的倍數,而且最小也是16k),建立執行緒大約需要90毫秒的建立時間;開啟大量執行緒會降低程式效能;執行緒越多,程式設計就越複雜,多個執行緒的資料共享等

什麼是主執行緒

  • 一個iOS程式執行後,預設會開啟1條執行緒,稱為“主執行緒”或“
    UI執行緒”
  • 主執行緒的主要作用:顯示\重新整理UI介面;處理UI事件(比如點選事件、滾動事件、拖拽事件等)
  • 主執行緒的使用注意:別將比較耗時的操作放到主執行緒中;耗時操作會卡住主執行緒,嚴重影響UI的流暢度,給使用者一種“卡”的壞體驗
  • 將耗時操作放在子執行緒(後臺執行緒、非主執行緒)

iOS中多執行緒的實現方案

  • pthread:一套通用的多執行緒API;適用於Unix\Linux\Windows等系統;跨平臺\可移植;使用難度大 (幾乎不使用)
  • NSThread:使用更加物件導向;簡單易用,可直接操作執行緒物件;
  • GCD:旨在替代NSThread等執行緒技術;充分利用裝置的多核;自動管理
  • NSOperation:基於GCD(底層是GCD);比GCD多了一些更簡單實用的功能;使用更加物件導向;自動管理

NSThread

  • 建立和啟動
    • 建立、啟動執行緒
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[thread start];
// 執行緒一啟動,就會線上程thread中執行self的run方法
  • 主執行緒相關用法
  + (NSThread *)mainThread; // 獲得主執行緒
  - (BOOL)isMainThread; // 是否為主執行緒
  + (BOOL)isMainThread; // 是否為主執行緒
  • 其他方法
  • 獲得當前執行緒
NSThread *current = [NSThread currentThread];
  • 其他建立執行緒方式
  • 建立執行緒後自動啟動執行緒:
   [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
  • 隱式建立並啟動執行緒:
  [self performSelectorInBackground:@selector(run) withObject:nil];
  • 上述2種建立執行緒方式的優缺點
    優點:簡單快捷
    缺點:無法對執行緒進行更詳細的設定

控制執行緒狀態

  • 啟動執行緒:
- (void)start;
// 進入就緒狀態 -> 執行狀態。當執行緒任務執行完畢,自動進入死亡狀態
  • 阻塞(暫停)執行緒:
 + (void)sleepUntilDate:(NSDate *)date;
 + (void)sleepForTimeInterval:(NSTimeInterval)time;
// 進入阻塞狀態
  • 強制停止執行緒:
 + (void)exit;// 進入死亡狀態

多執行緒多安全隱患

  • 一塊資源可能會被多個執行緒共享,也就是多個執行緒可能會訪問同一塊資源比如多個執行緒訪問同一個物件、同一個變數、同一個檔案
  • 當多個執行緒訪問同一塊資源時,很容易引發資料錯亂和資料安全問題

多執行緒多安全隱患解決

  • 互斥鎖使用格式
    @synchronized(鎖物件) { // 需要鎖定的程式碼 }
    注意:鎖定1份程式碼只用1把鎖,用多把鎖是無效的

  • 互斥鎖的優缺點
    優點:能有效防止因多執行緒搶奪資源造成的資料安全問題
    缺點:需要消耗大量的CPU資源

  • 互斥鎖的使用前提:多條執行緒搶奪同一塊資源

原子和非原子屬性

  • OC在定義屬性時有nonatomic和atomic兩種選擇
    atomic:原子屬性,為setter方法加鎖(預設就是atomic)
    nonatomic:非原子屬性,不會為setter方法加鎖
  • nonatomic和atomic對比
    atomic:執行緒安全,需要消耗大量的資源
    nonatomic:非執行緒安全,適合記憶體小的移動裝置
  • OS開發的建議:
    所有屬性都宣告為nonatomic
    儘量避免多執行緒搶奪同一塊資源
    儘量將加鎖、資源搶奪的業務邏輯交給伺服器端處理,減小移動客戶端的壓力

執行緒間通訊

  • 什麼叫做執行緒間通訊
    在1個程式中,執行緒往往不是孤立存在的,多個執行緒之間需要經常進行通訊

  • 執行緒間通訊的體現
    1個執行緒傳遞資料給另1個執行緒
    在1個執行緒中執行完特定任務後,轉到另1個執行緒繼續執行任務

  • 執行緒間通訊常用方法
-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
-(void)performSelector:(SEL)aSelector onThread:(NSThread *)thread withObject:(id)arg waitUntilDone:(BOOL)wait;

相關文章