加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

iOS多线程开发:几个容易被忽略的细节

发布时间:2019-06-07 03:29:58 所属栏目:业界 来源:Eternal_Love
导读:一样平常环境下,iOS开拓者只要会行使GCD、@synchronized、NSLock等几个简朴的API,就可以应对大部门多线程开拓了,不外这样是否真正做到了多线程安详,又是否真正充实操作了多线程的服从上风呢?看看以下几个轻易被忽略的细节。 读者写者题目(Readers-writers

在iOS中,上述代码中的PV原语可以替代成GCD中的信号量API,dispatch_semaphore_t来实现,可是必要特殊维护一个readerCount以及实现readerCount互斥会见的信号量,手动实现较量贫困,封装成同一接口有必然难度。不外亏得iOS开拓中可以找到现成的读者写者锁:

pthread_rwlock_t

这是一个迂腐的C说话层面的函数,用法如下:

  1. // Initialization of lock, pthread_rwlock_t is a value type and must be declared as var in order to refer it later. Make sure not to copy it. 
  2. var lock = pthread_rwlock_t() 
  3. pthread_rwlock_init(&lock, nil) 
  4.  
  5. // Protecting read section: 
  6. pthread_rwlock_rdlock(&lock) 
  7. // Read shared resource 
  8. pthread_rwlock_unlock(&lock) 
  9.  
  10. // Protecting write section: 
  11. pthread_rwlock_wrlock(&lock) 
  12. // Write shared resource 
  13. pthread_rwlock_unlock(&lock) 
  14.  
  15. // Clean up 
  16. pthread_rwlock_destroy(&lock) 

接口简捷可是却不友爱,必要留意pthread_rwlock_t是值范例,用=赋值会直接拷贝,不警惕就会挥霍内存,其它用完后还必要记得烧毁,轻易堕落,有没有更高级更易用的API呢?

GCD barrier

dispatch_barrier_async / dispatch_barrier_sync并不是专门用来办理读者写者题目的,barrier首要用于以了局景:当执行某一使命A时,必要该行列上之前添加的全部操纵都执行完,而之后添加进来的使命,必要守候使命A执行完毕才可以执行,从而到达将使命A断绝的目标,详细进程如下图所示:

iOS多线程开拓:几个轻易被忽略的细节

假如将barrier使命之前和之后的并发使命换为读操纵,barrier使命自己换为写操纵,就可以将dispatch_barrier_async / dispatch_barrier_sync当做读者写者锁来行使了,下面把文初的行使平凡锁实现的cache代码,用dispatch_barrier_async重写,做下比拟:

  1. //实现一个简朴的cache(行使平凡锁) 
  2. - (void)setCache:(id)cacheObject forKey:(NSString *)key { 
  3.     if (key.length == 0) { 
  4.         return; 
  5.     } 
  6.     [_cacheLock lock]; 
  7.     self.cacheDic[key] = cacheObject; 
  8.     ... 
  9.     [_cacheLock unlock]; 
  10.  
  11. - (id)cacheForKey:(NSString *key) { 
  12.     if (key.length == 0) { 
  13.         return nil; 
  14.     } 
  15.     [_cacheLock lock]; 
  16.     id cacheObject = self.cacheDic[key]; 
  17.     ... 
  18.     [_cacheLock unlock]; 
  19.     return cacheObject; 
  1. //实现一个简朴的cache(行使读者写者锁) 
  2. static dispatch_queue_t queue = dispatch_queue_create("com.gfzq.testQueue", DISPATCH_QUEUE_CONCURRENT); 
  3.  
  4. - (void)setCache:(id)cacheObject forKey:(NSString *)key { 
  5.     if (key.length == 0) { 
  6.         return; 
  7.     } 
  8.     dispatch_barrier_async(queue, ^{ 
  9.         self.cacheDic[key] = cacheObject; 
  10.         ... 
  11.     }); 
  12.  
  13. - (id)cacheForKey:(NSString *key) { 
  14.     if (key.length == 0) { 
  15.         return nil; 
  16.     } 
  17.     __block id cacheObject = nil; 
  18.     dispatch_sync(queue, ^{ 
  19.         cacheObject = self.cacheDic[key]; 
  20.         ... 
  21.     }); 
  22.     return cacheObject; 

这样实现的cache就可以并发执行读操纵,同时又有用地断绝了写操纵,分身了安详和服从。

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读