1.Mutex 互斥鎖.互斥鎖同一時間只運行同一個線程操作,如果當(dāng)一個線程正在持有鎖,其他的線程想要持有鎖,其他的線程會被阻塞,直到當(dāng)前持有鎖的線程釋放該鎖
? ?pthread_mutexattr_t mutexattr;
? ? pthread_mutexattr_init(&mutexattr);
? ? int re = pthread_mutex_init(&_mutex, &mutexattr);
? __block int value = 0;
? ? for (int i = 0; i<999; i++) {
? ? ? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{
? ? ? ? ? ? pthread_mutex_lock(&_mutex);
?? ? ? ? ? ?value++;
? ? ? ? ? ? pthread_mutex_unlock(&_mutex);
? ? ? ? });
? ? }
? ? pthread_mutex_destroy(&_mutex);
? ? pthread_mutexattr_destroy(&mutexattr);
?ps:NSLock其實就是封裝的pthread_mutex_lock
2.Recursive lock 遞歸鎖.遞歸鎖是互斥鎖的一個變種.遞歸鎖運行一個線程多次加鎖,其他線程請求鎖的時候同樣會阻塞直到持有鎖的線程釋放鎖.遞歸鎖加鎖次數(shù)和解鎖次數(shù)必須一一對應(yīng),否則會無法釋放鎖.一般遞歸鎖用在遞歸函數(shù)內(nèi)部加鎖.
3.Read-write lock 讀寫鎖.讀寫鎖一般用來大量的讀寫操作的時候.當(dāng)你想要寫操作時,必須等到讀操作完成,釋放讀的鎖,當(dāng)你想要讀的操作時,必須等到寫的操作完成釋放寫的鎖.
pthread_rwlockattr_init(&_rwAttr);
? int re = pthread_rwlock_init(&_rwLock, &_rwAttr);
? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{
? ? ? ? pthread_rwlock_wrlock(&_rwLock);
? ? ? ? NSLog(@"rwLock fro Writing%@",[NSThread currentThread]);
? ? ? ? sleep(3);
? ? ? ? NSLog(@"unlock fro Writing");
? ? ? ? pthread_rwlock_unlock(&_rwLock);
? ? });
? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{
? ? ? ? pthread_rwlock_rdlock(&_rwLock);
? ? ? ? NSLog(@"rwLock fro Reading%@",[NSThread currentThread]);
? ? ? ? sleep(2);
? ? ? ? NSLog(@"unlock fro Reading");
? ? ? ? pthread_rwlock_unlock(&_rwLock);
? ? });
? ? pthread_rwlockattr_destroy(&_rwAttr);
? ? pthread_rwlock_destroy(&_rwLock);
4.Distributed lock 分散鎖.分散鎖提供了一個在進程級別的互斥操作.分散鎖不會阻塞其他的進程.它僅僅想想要上鎖的進程報告當(dāng)前鎖的狀態(tài)是busy.讓進程覺得如何繼續(xù)處理
ps:NSDistributedLock一般用于多個APP調(diào)度操作文件系統(tǒng)的文件
5.Spin lock 自旋鎖.自旋鎖通過不停的輪詢條件來控制線程的操作.自旋鎖的輪詢機制使得其比他的的阻塞操作效率要高.但是注意,自旋鎖已經(jīng)不安全了,不要使用.
6.NSConditionLock 條件鎖.條件鎖是通過一個條件來使用mutex加鎖,解鎖的.一般情況下,條件鎖使用的情況是當(dāng)線程執(zhí)行任務(wù)需要在指定條件下執(zhí)行時.比較經(jīng)典的就是生產(chǎn)者和消費者
NSConditionLock * condition = [[NSConditionLock alloc]initWithCondition:lockValue];
? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{
? ? ? ? [condition lockWhenCondition:lockValue];
? ? ? ? NSLog(@"productor lock%@",[NSThread currentThread]);
? ? ? ? sleep(2);
? ? ? ? NSLog(@"productor unlock");
? ? ? ? [condition unlockWithCondition:unlockValue];
? ? });
? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{
? ? ? ? [condition lockWhenCondition:unlockValue];
? ? ? ? NSLog(@"consumer lock%@",[NSThread currentThread]);
? ? ? ? sleep(3);
? ? ? ? NSLog(@"consumer unlock");
? ? ? ? [condition lockWhenCondition:lockValue];
? ? });
7.NSCondition . 條件相當(dāng)于一個鎖和一個臨界條件的結(jié)合.鎖會阻塞其他線程,保護數(shù)據(jù),條件會保證在特定條件下執(zhí)行任務(wù).如果條件為假則會阻塞線程直到signal 發(fā)出之后,確定條件為真.
7.Deadlocks和Livelocks
deadLocks :任何時候當(dāng)一個線程想要在同一時間獲取多個鎖都有可能發(fā)生死鎖.當(dāng)兩個不同的線程都持有對方所需要的鎖(加鎖的資源),并且嘗試獲取另一個線程持有的鎖(加鎖的資源),就會發(fā)生死鎖,因為每個線程都會被阻塞,無法獲取對方的鎖
liveLocks:類似于死鎖,兩個不同的線程競爭同一個資源時,有一個線程先放棄自己的鎖,想要獲取第二個鎖,一旦它獲取到第二個鎖之后她又回頭獲取第一個自己放棄的鎖.此時線程就被鎖定了,因為線程一直重復(fù)的獲取鎖.
避免deadLocks 和 liveLocks 的方法就是保證同一時間只有一個鎖.假如不能避免有多個鎖,那就應(yīng)該保證其他的線程不要去搶占這個鎖.
ps:Core Foundation 是線程安全的.但是Foundation不是全部線程安全的,想要知道哪些類是線程安全的請參考Thread Safety Summary