Grand Central Dispatch:队列与信号量用于控制对数据结构的访问?

发布于 2024-10-19 05:58:45 字数 322 浏览 8 评论 0原文

我正在与 Macruby 一起做这件事,但我认为这在这里并不重要。

我有一个模型,它将其状态存储在字典数据结构中。我希望并发操作偶尔更新此数据结构。在我看来,GCD 对此提供了一些可能的解决方案,包括这两个:

  • 将访问数据结构的任何代码包装在发送到某个串行队列的块中
  • ,使用 GCD 信号量,客户端代码在必要时发送等待/信号调用访问结构

当第一个解决方案中的队列被同步调用时,它看起来与信号量解决方案几乎相同。这些解决方案是否具有我所缺少的明显优势?我缺少更好的选择吗?

另外:用 GCD 实现读写(共享独占)锁会很简单吗?

I'm doing this with Macruby, but I don't think that should matter much here.

I've got a model which stores its state in a dictionary data structure. I want concurrent operations to be updating this data structure sporadically. It seems to me like GCD offers a few possible solutions to this, including these two:

  • wrap any code that accesses the data structure in a block sent to some serial queue
  • use a GCD semaphore, with client code sending wait/signal calls as necessary when accessing the structure

When the queues in the first solution are synchronously called, then it seems pretty much equivalent to the semaphore solution. Do either of these solutions have clear advantages that I'm missing? Is there a better alternative I'm missing?

Also: would it be straightforward to implement a read-write (shared-exclusive) lock with GCD?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怎会甘心 2024-10-26 05:58:45

串行队列的

  • 优点
    • 没有任何锁
  • 缺点
    • 任务不能在串行队列中同时工作

GCD Semaphore

  • Pros
    • 任务可以同时工作
  • 工作
    • 尽管重量轻,但它使用锁

。我们还可以使用原子操作而不是 GCD 信号量。在某些情况下它会比 GCD Semaphore 更轻。

同步工具 - 原子操作

Serial Queue

  • Pros
    • there are not any lock
  • Cons
    • tasks can't work concurrently in the Serial Queue

GCD Semaphore

  • Pros
    • tasks can work concurrently
  • Cons
    • it uses lock even though it is light weight

Also we can use Atomic Operations instead of GCD Semaphore. It would be lighter than GCD Semaphore in some situation.

Synchronization Tools - Atomic Operations

避讳 2024-10-26 05:58:45

在串行队列上使用dispatch_sync保护对数据结构的访问在语义上等同于使用调度信号量,并且在无竞争的情况下,它们都应该非常快。如果性能很重要,请进行基准测试并查看是否有任何显着差异。

至于读写锁,你确实可以在 GCD 之上构建一个——至少,我前几天拼凑了一些东西 这里这似乎有效。 (警告:存在龙/未经充分测试的代码。)我的解决方案在提交到全局并发队列之前通过中间串行队列传输读/写请求。串行队列在适当的时间挂起/恢复,以确保写请求串行执行。

我想要一些可以模拟允许同步点的私有并发调度队列的东西 - 公共 GCD api 中没有公开的东西,但是 强烈暗示未来。

Guarding access to the data structure with dispatch_sync on serial queue is semantically equivalent to using a dispatch semaphore, and in the uncontended case, they should both be very fast. If performance is important, benchmark and see if there's any significant difference.

As for the readers-writer lock, you can indeed construct one on top of GCD—at least, I cobbled something together the other day here that seems to work. (Warning: there be dragons/not-well-tested code.) My solution funnels the read/write requests through an intermediary serial queue before submitting to a global concurrent queue. The serial queue is suspended/resumed at the appropriate times to ensure that write requests execute serially.

I wanted something that would simulate a private concurrent dispatch queue that allowed for synchronisation points—something that's not exposed in the public GCD api, but is strongly hinted at for the future.

阪姬 2024-10-26 05:58:45

在之前的答案中添加一个警告(最终成为调度队列的一个缺点)。

您需要小心调度队列的调用方式,因为有一些隐藏的场景在我遇到它们之前对我来说并不明显。

我用调度队列替换了许多关键部分上的 NSLock 和 @synchronized,目的是实现轻量级同步。不幸的是,我遇到了导致死锁的情况,我已将其恢复为使用dispatch_barrier_async/dispatch_sync模式。即使您创建并发队列,dispatch_sync 似乎也可能会机会性地在主队列上调用其块(如果已经在那里执行)。这是一个问题,因为当前调度队列上的dispatch_sync 会导致死锁。

我想我会向后移动并在这些区域使用另一种锁定技术。

Adding a warning (which ends up being a con for dispatch queues) to the previous answers.

You need to be careful of how the dispatch queues are called as there are some hidden scenarios that were not immediately obvious to me until I ran into them.

I replaced NSLock and @synchronized on a number of critical sections with dispatch queues with the goal of having lightweight synchronization. Unfortunately, I ran into a situation that results in a deadlock and I have pieced it back to using the dispatch_barrier_async / dispatch_sync pattern. It would seem that dispatch_sync may opportunistically call its block on the main queue (if already executing there) even when you create a concurrent queue. This is a problem since dispatch_sync on the current dispatch queue causes a deadlock.

I guess I'll be moving backwards and using another locking technique in these areas.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文