在objective-c中,存在(至少)两种同步并发访问共享资源的方法。旧的基于锁的方法和Grand Central Dispatch(GCD)的新方法,后者使用dispatch_sync将所有访问分派到共享队列。
在Concurrency Programming Guide, section Eliminating Lock-Based Code中,声明“使用锁定需要付出代价。即使在无争议的情况下,锁定也会导致性能损失。”
这是GCD方法的有效论据吗?
我认为这不是出于以下原因:
队列必须具有要执行的排队任务列表。一个或多个线程可以通过dispatch_sync向此列表添加任务,并且一个或多个工作线程需要从此列表中删除元素才能执行任务。必须用锁来保护它。因此也需要锁定。
如果没有我不知道的锁定,请告诉我队列是否可以做到这一点。
更新:在指南中进一步说明,有一些我不知道的事情:“排队任务不需要陷入内核来获取互斥锁。”< / p>
这是如何运作的?
答案 0 :(得分:2)
在OS X和iOS的当前版本中,pthread互斥体和GCD队列(以及GCD信号量)都完全在用户空间中实现,而不需要陷入内核,除非存在争用(即线程阻塞)内核等待“解锁”)。
GCD队列对锁的概念优势更多的是它们能够异步使用,队列中“锁定”关键部分的异步执行不需要等待。
如果您只是通过调用dispatch_sync
来替换锁,那么您并没有真正充分利用GCD的功能(尽管dispatch_sync
的实现恰好由于pthread互斥量而略微提高效率必须满足额外的限制)。
答案 1 :(得分:0)
存在无锁排队实现。他们经常嗤之以鼻的一个原因是它们是特定于平台的,因为它们依赖于处理器的原子操作(如递增,递减,比较和交换等),并且这些操作的确切实现将因CPU架构而异。另一个。由于Apple既是操作系统和硬件供应商,这种批评对苹果平台来说远不是一个问题。
文档的含义是GCD队列管理使用其中一个无锁队列来实现线程安全而不会陷入内核。
有关一个可能的MacOS / iOS无锁队列实现的更多信息,请阅读here有关这些功能的信息:
void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset);
void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset);
值得一提的是,GCD(主要)是开源的,所以如果你对它的队列的实现真的很好奇,那就去找use the source,Luke。