1. 程式人生 > 其它 >iOS 幾種常用鎖介紹

iOS 幾種常用鎖介紹

https://www.jianshu.com/p/57667e2217a5

https://blog.csdn.net/liupinghui/article/details/67637830

  • NSLock
    • NSLock是Cocoa提供給我們最基本的鎖物件,這也是我們經常使用的,除lock和unlock外,NSLock還提供了tryLock和lockBeforeDate:兩個方法,前一個方法會嘗試加鎖,如果鎖不可用(已經被鎖住),並不會阻塞執行緒,直接返回NO。後一個方法則會在指定的Date之前嘗試加鎖,如果在指定的時間內都不能加鎖,則返回NO
  • synchronized(互斥鎖)
    • synchronized會建立一個異常捕獲handler和一些內部的鎖,所以使用@synchronized替換普通鎖的代價是要付出更多的時間消耗
    • 建立給給@synchronized指令的物件是一個用來區別保護塊的唯一識別符號。如果你在兩個不同的執行緒裡面執行上述方法,每次在一個執行緒傳遞了一個不同的物件給anObj引數,那麼每次都將會擁有它的鎖,並持續處理,中間不會被其他執行緒阻塞。然而如果你傳遞的是同一個物件,那麼多個執行緒中的一個執行緒會首先獲得該鎖,而其他執行緒將會被阻塞,直到第一個執行緒完成它的臨界區
    • 作為一個預防措施。@synchronized塊隱式的新增一個異常處理例程來保護程式碼,該處理例程會在異常丟擲的時候自動的釋放互斥鎖,這就意味著為了使用@synchronized指令,你必須在你的程式碼中啟用異常處理。如果你不想讓隱式的異常處理例程帶來額外的開銷,那麼可以使用其他的鎖
  • atomic
    • atomic只是給成員變數的set和get方法加了一個鎖,防止多執行緒一直去讀寫這個成員變數。但這也僅僅是對讀寫的鎖定,並不是執行緒安全。而且使用atomic比nonatomic慢了將近20倍
  • OSSpinlock
    • 自旋鎖
    • 耗時最少
    • 自旋鎖幾乎不進入核心,僅僅是重新載入自旋鎖
    • 如果自旋鎖被佔用時間在一百納秒以內,效能還是比較高的,因為減少了代價較高的系統呼叫和一系列的上下文切換
    • 但是該鎖不是萬能的,如果該鎖佔用的時間比較多的時候,使用該鎖會導致佔用的cpu較多
  • pthread_mutex
    • 是底層的API,在各種加鎖方式中屬於效能比較高的
    • 如果自旋鎖佔用的時間比較多,那麼使用pthread是一個不錯的選擇
  • NSConditionLock(條件鎖)
    • 條件鎖與特定的使用者定義的條件有關,它可以確保一個執行緒可以獲取滿足一定條件的鎖
    • 內部涉及到訊號量機制,一旦一個執行緒獲取鎖以後,它可以放棄鎖並設定相關條件,這時候其他執行緒競爭該鎖
    • 執行緒之間的競爭激烈,涉及到條件鎖檢測、執行緒間通訊,系統呼叫、下文切換比較頻繁
  • NSRecursiveLock遞迴鎖
    • NSRecursiveLock實際上定義的是一個遞迴鎖,這個鎖可以被同一執行緒多次請求,而不會引起死鎖。這主要是用在迴圈或者遞迴操作中
  • 總結:
    • 如果只是粗略的使用鎖,不考慮效能可以使用synchronized
    • 如果對效率有較高的要求,採用OSSpinLock
    • 因為pthread的鎖也是使用OSSpinLock實現的,而且在OSSpinLock的實現過程中,並沒有進入系統kernel,使用OSSpinLock可以節省系統呼叫和上下文切換
    • NSLock/NSConditionLock/NSRecursiveLock耗時接近。220ms左右
    • dispatch_barrier_async的效能並沒有我們想象中的那樣好,這與執行緒同步排程開銷有關


作者:深度碼農患者
連結:https://www.jianshu.com/p/57667e2217a5
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。