1

在 Objective-c 中,(至少)有两种方法可以同步对共享资源的并发访问。较旧的基于锁的方法和带有 Grand Central Dispatch (GCD) 的较新方法,后者使用 dispatch_sync 将所有访问分派到共享队列。

Concurrency Programming Guide 的 Elimination Lock-Based Code 一节中,它指出“使用锁是有代价的。即使在没有争议的情况下,使用锁总是会带来性能损失。”

这是 GCD 方法的有效论据吗?

我认为不是以下原因:

队列必须有一个队列任务列表来执行。一个或多个线程可以通过 dispatch_sync 将任务添加到此列表中,并且一个或多个工作线程需要从该列表中删除元素才能执行任务。这必须由锁保护。所以那里也需要锁。

请告诉我是否有任何其他方式队列可以在没有我不知道的锁的情况下执行此操作。

更新:在指南的进一步内容中,暗示有一些我不知道的事情:“排队任务不需要陷入内核来获取互斥锁。”

这是如何运作的?

4

2 回答 2

2

在当前的 OS X 和 iOS 版本中,pthread 互斥锁和 GCD 队列(以及 GCD 信号量)都是在用户空间中实现的,无需陷入内核,除非存在争用(即内核中的线程阻塞等待等待“解锁”)。

GCD 队列相对于锁的概念优势更多地在于它们能够异步使用,队列上“锁定”关键部分的异步执行不涉及任何等待。

如果您只是用调用来替换锁,dispatch_sync那么您并没有真正充分利用 GCD 的特性(尽管dispatch_sync主要由于 pthread 互斥体必须满足额外的约束,实现的效率会稍微高一些)。

于 2013-09-05T21:45:57.483 回答
0

存在无锁队列实现。它们经常被嘲笑的一个原因是它们是特定于平台的,因为它们依赖于处理器的原子操作(如递增、递减、比较和交换等),并且这些操作的确切实现会因 CPU 架构不同而异。其他。由于 Apple 既是操作系统又是硬件供应商,因此这种批评对于 Apple 平台来说远不是问题。

文档的含义是 GCD 队列管理使用这些无锁队列之一来实现线程安全,而不会陷入内核。

有关一种可能的 MacOS/iOS 无锁队列实现的更多信息,请在此处阅读有关这些功能的信息:

void  OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset);
void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset);

这里值得一提的是,GCD 已经(大部分)开源,所以如果你真的对它的队列的实现感到好奇,请继续使用源代码,Luke。

于 2013-09-04T11:08:56.740 回答