- 同一時(shí)間暖夭,只能有1個(gè)線程進(jìn)行寫(xiě)的操作
- 同一時(shí)間锹杈,允許有多個(gè)線程進(jìn)行讀的操作
- 同一時(shí)間,不允許既有寫(xiě)的操作迈着,又有讀的操作
上面這樣的場(chǎng)景就是典型的“多讀單寫(xiě)”竭望,經(jīng)常用于文件等數(shù)據(jù)的讀寫(xiě)操作,iOS中的實(shí)現(xiàn)方案有:
-
pthread_rwlock
讀寫(xiě)鎖 (內(nèi)部已經(jīng)實(shí)現(xiàn)了) -
dispatch_barrier_async
異步柵欄調(diào)用
1裕菠、pthread_rwlock
讀寫(xiě)鎖
- 讀寫(xiě)鎖方法列表
// 初始化鎖
pthread_rwlock_t lock;
pthread_rwlock_init(&lock, NULL);
// 讀-加鎖
pthread_rwlock_rdlook(&lock);
// 讀-嘗試加鎖
pthread_rwlock_tryrdlock(&lock);
// 寫(xiě)-加鎖
pthread_rwlock_wrlock(&lock);
// 寫(xiě)-嘗試加鎖
pthread_rwlock_trywrlock(&lock);
// 解鎖
pthread_rwlock_unlock(&lock);
// 鎖毀
pthread_rwlock_destroy(&lock);
- 初始化一把鎖:
@property(assgin, nonatomic) pthread-rwlock_t lock;
// init
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);
// 讀操作
pthread_rwlock_unlock(&_lock);
}
-(void)write
{
pthread_rwlock_wrlock(&_lock);
// 寫(xiě)操作
pthread_rwlock_unlock(&_lock);
}
2咬清、dispatch_barrier_async
- 這個(gè)函數(shù)傳入的并發(fā)隊(duì)列必須是自己通過(guò)
dispatch_queue-create
創(chuàng)建的,全局并發(fā)隊(duì)列或串行隊(duì)列是沒(méi)有效果的 - 如果傳入的是一個(gè)串行隊(duì)列或是一個(gè)全局的并發(fā)隊(duì)列糕韧,那這個(gè)函數(shù)便等同于
dispatch_async
函數(shù)的效果
// 初始化隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("rw_queue", DISPATCH_QUEUE_CONCURRENT);
// 讀
dispatch_async(queue, ^{
});
// 寫(xiě)
dispatch_barrier_async(queue, ^{
});
// 建立了一個(gè)柵欄的東西枫振, 起一個(gè)柵欄喻圃,在寫(xiě)的前后樹(shù)立一個(gè)屏障萤彩,把寫(xiě)的任務(wù)執(zhí)行完,才可以繼續(xù)其它操作
例:讀可以同時(shí)讀斧拍,寫(xiě)不一樣了雀扶,因?yàn)榻⒘似琳希荒艿纫粋€(gè)寫(xiě)操作執(zhí)行完肆汹,才會(huì)繼續(xù)其它的讀操作和下一次寫(xiě)操作愚墓。
{
self.queue = dispatch_queue-createa("rw_queue", DISPATCH_QUEUE_CONCURRENT);
}
-(void)read
{
dispatch_async(self. queue, &{
// 讀
});
}
-(void)write
{
dispatch_barrier_async(queue, ^{
// 寫(xiě)
});
}