OC原理之多線程中的鎖(一)

OSSpinLock

OSSpinLock叫作"自旋鎖",等待鎖的線程會處於忙等狀態,一直佔用着cpu資源。因爲可能會出現優先級反轉的問題,是個不安全鎖。在iOS10蘋果已經不推薦使用了安全

優先級反轉問題

若是等待鎖的線程優先級較高,它會一直佔用着CPU資源,優先級低的線程就沒法釋放 使用的時候須要導入#import <libkern/OSAtomic.h>併發

使用代碼

OSSpinLock lock = OS_SPINLOCK_INIT;
bool result = OSSpinLockTry(lock);// 嘗試加鎖(若是須要等待就不加鎖,直接返回false,若是不須要等待就加鎖,返回true)
OSSpinLockLock(lock); // 加鎖
OSSpinLockUnlock(lock);// 不加鎖

os_unfair_lock

os_unfair_lock用於取代不安全的OSSpinLock,iOS10之後才支持spa

相比較於OSSpinLock的區別,等待os_unfair_lock鎖的線程會處於休眠狀態,並不是忙等線程

使用時,如要導入頭文件#import <os/lock.h>code

使用代碼

os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
bool result = os_unfair_lock_trylock(&lock); // 嘗試加鎖 返回值=是否加鎖成功
os_unfair_lock_lock(&lock); // 加鎖
os_unfair_lock_unlock(&lock); // 解鎖

pthread_mutex

mutex叫作"互斥鎖",等待鎖的線程會處於休眠狀態blog

須要導入頭文件#import <pthread.h>遞歸

使用代碼

// 初始化鎖的屬性
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
    
// 初始化鎖
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, &attr);
    
// 嘗試加鎖
bool result = pthread_mutex_trylock(&mutex);
    
// 加鎖
pthread_mutex_lock(&mutex);
    
// 解鎖
pthread_mutex_unlock(&mutex);
    
// 銷燬相關資源
pthread_mutexattr_destroy(&attr);
pthread_mutex_destroy(&mutex);

pthread_mutex - 遞歸鎖

遞歸鎖的話,建立方式與互斥鎖的方式相同,只是在建立pthread_mutexattr_t的以後,設置類型爲PTHREAD_MUTEX_RECURSIVE隊列

pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

pthread_mutex – 條件

使用代碼:資源

// 初始化鎖
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
    
// 初始化條件
pthread_cond_t condition;
pthread_cond_init(&condition, NULL);
    
// 等待條件(進入休眠,放開mutex鎖,被喚醒後,會再次對mutex加鎖)
pthread_cond_wait(&condition, &mutex);
// 激活一個等待該條件的線程
pthread_cond_signal(&condition);
// 激活全部等待該條件的線程
pthread_cond_broadcast(&condition);
    
// 銷燬
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&condition);

NSLock

NSLock是對mutex普通鎖的封裝同步

NSRecursiveLock

NSrecursiveLock是對mutex遞歸鎖的封裝

NSCondition

NSCondition是對mutex和cond的封裝

dispatch_semaphore

semaphore叫作"信號量"

信號量的初始值,能夠用來控制線程併發訪問的最大數量

信號量的初始值爲1,表明同時只容許一條線程訪問資源,保證線程同步

使用代碼:

// 信號量的初始值
int value = 1;
// 初始化信號量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(value);
// 若是信號量的值<=0,當前線程就會進入休眠等待(知道信號量的值>0)
// 若是信號量的值>0,就減1,而後往下執行後面的代碼
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 讓信號量的值加1
dispatch_semaphore_signal(semaphore);

dispatch_queue

直接使用GCD的串行隊列,也是能夠顯示線程同步的

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
        
});

@synchronized

@synchronized是對mutex遞歸鎖的封裝

源碼查看:objc4中的objc-sync.mm文件

@synchronized(obj)內部會生成obj對應的遞歸鎖,而後進行加鎖、解鎖操做

使用代碼:

@synchronized (object) {
        
}
相關文章
相關標籤/搜索