iOS-多線程03-多線程知識(shí)點(diǎn)補(bǔ)充

在上一篇文章中,我們主要了解了多線程安全隱患,以及它的解決方案。其中,我們有了解到自旋鎖和互斥鎖,這兩種經(jīng)常用到的鎖。這里有一個(gè)大致的總結(jié),看看這兩個(gè)鎖在什么情況下比較合適:

1、什么情況使用自旋鎖比較劃算?
預(yù)計(jì)線程等待鎖的時(shí)間很短
加鎖的代碼(臨界區(qū))經(jīng)常被調(diào)用,但競(jìng)爭(zhēng)情況很少發(fā)生
CPU資源不緊張
多核處理器
什么情況使用互斥鎖比較劃算?
2、預(yù)計(jì)線程等待鎖的時(shí)間較長(zhǎng)
單核處理器
臨界區(qū)有IO操作
臨界區(qū)代碼復(fù)雜或者循環(huán)量大
臨界區(qū)競(jìng)爭(zhēng)非常激烈

接下來,我們?cè)倏戳硪粋€(gè)知識(shí)點(diǎn),是關(guān)于讀寫安全方面的知識(shí),首先我們來認(rèn)識(shí)下atomic這個(gè)修飾符,在iOS這個(gè)修飾符的作用就是保證屬性setter、getter的原子性操作,相當(dāng)于在getter和setter內(nèi)部加了線程同步的鎖,它能保證在單個(gè)讀和寫的過程中是安全的,但是它并不能保證使用屬性的過程是線程安全的。
這里,我們就針對(duì)這個(gè)使用屬性過程的線程安全問題來看下,首先,我們需要了解方案的具體要求。大致如下:
1、同一時(shí)間,只能有1個(gè)線程進(jìn)行寫的操作。
2、同一時(shí)間,允許有多個(gè)線程進(jìn)行讀的操作。
3、同一時(shí)間,不允許既有寫的操作,又有讀的操作。
總結(jié)一句話的意思,就是“多讀單寫”,就是可以多條線程同時(shí)讀取,但是在寫入的時(shí)候,只能有一條線程在操作這個(gè)屬性。iOS的常用實(shí)現(xiàn)方案有:
1、pthread_rwlock:讀寫鎖
2、dispatch_barrier_async:異步柵欄
先來看看C語(yǔ)言中的讀寫鎖pthread_rwlock的使用:

- (void)demo {
    
    pthread_rwlock_init(&_lock, NULL);
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            [self read];
        });
        dispatch_async(queue, ^{
            [self write];
        });
    }
}

- (void)read {
    pthread_rwlock_rdlock(&_lock);
    sleep(1);
    NSLog(@"read");
    pthread_rwlock_unlock(&_lock);
}

- (void)write
{
    pthread_rwlock_wrlock(&_lock);
    sleep(1);
    NSLog(@"write");
    pthread_rwlock_unlock(&_lock);
}

- (void)dealloc {
    pthread_rwlock_destroy(&_lock);
}


打印結(jié)果如下圖:


image.png

我們可以很清楚的發(fā)現(xiàn),只有在read操作的時(shí)候,是有多條線程同時(shí)打印的,任何write操作,都是會(huì)有1秒鐘的間隔。
接下來,我們來看看異步柵欄操作:

- (void)demo {

    dispatch_queue_t queue = dispatch_queue_create("rw_queue", DISPATCH_QUEUE_CONCURRENT);

    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            [self read];
        });
        
        dispatch_async(queue, ^{
            [self read];
        });
        
        dispatch_async(queue, ^{
            [self read];
        });
        
        dispatch_barrier_async(queue, ^{
            [self write];
        });
    };
}

- (void)read {
    sleep(1);
    NSLog(@"read");
}

- (void)write
{
    sleep(1);
    NSLog(@"write");
}

打印結(jié)果如下:


image.png

也是我們所希望看到的結(jié)果。
不過這里有個(gè)必要的點(diǎn),我們需要了解下,就是創(chuàng)建的queue必須是自定義的DISPATCH_QUEUE_CONCURRENT,如果是自定義串行隊(duì)列或者直接使用全局并發(fā)隊(duì)列,那么dispatch_barrier_async這個(gè)函數(shù)等同于dispatch_async!
以上就是這次對(duì)多線程知識(shí)點(diǎn)總結(jié)的補(bǔ)充內(nèi)容!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、簡(jiǎn)介:多線程在之前進(jìn)行過一篇詳細(xì)的基礎(chǔ)博客 iOS多線程 二、多線程的基礎(chǔ)知識(shí)回顧 1.1、iOS中的常見多線...
    IIronMan閱讀 1,040評(píng)論 0 4
  • Q:為什么出現(xiàn)多線程? A:為了實(shí)現(xiàn)同時(shí)干多件事的需求(并發(fā)),同時(shí)進(jìn)行著下載和頁(yè)面UI刷新。對(duì)于處理器,為每個(gè)線...
    幸福相依閱讀 1,732評(píng)論 0 2
  • 前言 iOS開發(fā)中由于各種第三方庫(kù)的高度封裝,對(duì)鎖的使用很少,剛好之前面試中被問到的關(guān)于并發(fā)編程鎖的問題,都是一知...
    喵渣渣閱讀 3,878評(píng)論 0 33
  • 1. iOS中的互斥鎖 在編程中,引入對(duì)象互斥鎖的概念,來保證共享數(shù)據(jù)操作的完整性。每個(gè)對(duì)象都對(duì)應(yīng)于一個(gè)可稱為“互...
    歡博閱讀 979評(píng)論 0 1
  • 60秒學(xué)演講,你會(huì)每天不一樣,堅(jiān)持日記,記錄自己精彩人生!大家好,我是龍兄老師的迷弟,楊帆! 今天中午跟朋友一起吃...
    楊帆_cc94閱讀 794評(píng)論 0 0

友情鏈接更多精彩內(nèi)容