【问题标题】:Does dispatch_sync have a conceptual performance advantage over a lock?与锁相比,dispatch_sync 是否具有概念上的性能优势?
【发布时间】:2013-09-04 10:24:37
【问题描述】:

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

Concurrency Programming Guide, section Eliminating Lock-Based Code 中,声明“使用锁是有代价的。即使在无争议的情况下,使用锁总是会带来性能损失。”

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

我认为不是以下原因:

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

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

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

它是如何工作的?

【问题讨论】:

标签: objective-c concurrency locking grand-central-dispatch


【解决方案1】:

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

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

如果您只是用调用dispatch_sync 来替换锁,那么您并没有真正充分利用GCD 的功能(尽管dispatch_sync 的实现恰好更有效,主要是因为pthread 互斥锁必须满足额外的约束)。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • FWIW OSAtomicEnqueue/OSAtomicDequeue 不是 GCD 内部使用的,该 API 实现了无锁 LIFO 队列(堆栈),而 GCD 队列使用无锁 FIFO 队列算法实现。
    • 是的。我只是指出存在无锁队列实现,并且 GCD 源可用。 OSAtomic* 的东西只是在证明这一点时很容易参考的一种实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 2021-01-03
    相关资源
    最近更新 更多