iOS-多線程03-多線程知識點補充

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

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

接下來,我們再看另一個知識點,是關于讀寫安全方面的知識,首先我們來認識下atomic這個修飾符,在iOS這個修飾符的作用就是保證屬性setter、getter的原子性操作,相當于在getter和setter內部加了線程同步的鎖,它能保證在單個讀和寫的過程中是安全的,但是它并不能保證使用屬性的過程是線程安全的。
這里,我們就針對這個使用屬性過程的線程安全問題來看下,首先,我們需要了解方案的具體要求。大致如下:
1、同一時間,只能有1個線程進行寫的操作。
2、同一時間,允許有多個線程進行讀的操作。
3、同一時間,不允許既有寫的操作,又有讀的操作。
總結一句話的意思,就是“多讀單寫”,就是可以多條線程同時讀取,但是在寫入的時候,只能有一條線程在操作這個屬性。iOS的常用實現方案有:
1、pthread_rwlock:讀寫鎖
2、dispatch_barrier_async:異步柵欄
先來看看C語言中的讀寫鎖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);
}


打印結果如下圖:


image.png

我們可以很清楚的發(fā)現,只有在read操作的時候,是有多條線程同時打印的,任何write操作,都是會有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");
}

打印結果如下:


image.png

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

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

相關閱讀更多精彩內容

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

友情鏈接更多精彩內容