如何實(shí)現(xiàn)以下場(chǎng)景糠聪,“多讀單寫”,經(jīng)常用于文件等數(shù)據(jù)的讀寫操作
- 同一時(shí)間声旺,只能有1個(gè)線程進(jìn)行寫的操作
- 同一時(shí)間笔链,允許有多個(gè)線程進(jìn)行讀的操作
- 同一時(shí)間,不允許既有寫的操作腮猖,又有讀的操作
iOS中的實(shí)現(xiàn)方案有:
1. pthread_rwlock: 讀寫鎖
2. dispatch_barrier_async: 異步柵欄調(diào)用
pthread_rwlock:讀寫鎖
等待鎖的線程會(huì)進(jìn)入休眠
#import <pthread.h> // 導(dǎo)入頭文件
@interface ViewController ()
@property (nonatomic ,assign) pthread_rwlock_t lock; // 定義一個(gè)鎖屬性
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 初始化鎖
pthread_rwlock_init(&_lock, NULL);
}
// 讀取數(shù)據(jù)的方法
- (void)read
{
// 讀-加鎖
pthread_rwlock_rdlock(&_lock);
// 讀取數(shù)據(jù)的代碼
NSLog(@"讀取數(shù)據(jù)%s", __func__);
// 讀完-解鎖
pthread_rwlock_unlock(&_lock);
}
// 寫入數(shù)據(jù)的方法
- (void)write
{
// 寫-加鎖
pthread_rwlock_wrlock(&_lock);
// 寫入數(shù)據(jù)的代碼
NSLog(@"寫入數(shù)據(jù)%s", __func__);
// 寫完-解鎖
pthread_rwlock_unlock(&_lock);
}
- (void)dealloc
{
// 用完銷毀鎖
pthread_rwlock_destroy(&_lock);
}
其中的方法如下圖
截屏2020-08-06 上午10.27.21.png
dispatch_barrier_async:異步柵欄調(diào)用
- 這個(gè)函數(shù)傳入的并發(fā)隊(duì)列必須是自己通過dispatch_queue_create創(chuàng)建的
- 如果傳入的是一個(gè)串行或是一個(gè)全局的并發(fā)隊(duì)列鉴扫,那這個(gè)函數(shù)便等同于dispatch_async函數(shù)的效果
/** 異步柵欄調(diào)用的并發(fā)隊(duì)列 */
@property (nonatomic, strong) dispatch_queue_t queue;
// 創(chuàng)建隊(duì)列,必須是自己創(chuàng)建的隊(duì)列澈缺,不能是全局的并發(fā)隊(duì)列
_queue = dispatch_queue_create("rwqueue", DISPATCH_QUEUE_CONCURRENT);
// 異步讀取
dispatch_async(_queue, ^{
// 讀取的代碼
});
// 柵欄調(diào)用寫入坪创,這樣就能保證線程安全的寫炕婶,并且不能有其他線程調(diào)用
dispatch_barrier_async(_queue, ^{
// 寫入的代碼
});