4

我正在使用 Macruby 进行此操作,但我认为这在这里并不重要。

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

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

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

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

4

3 回答 3

0

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

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

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

于 2011-05-06T11:49:16.183 回答
0

串行队列

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

GCD 信号量

  • 优点
    • 任务可以同时工作
  • 缺点
    • 即使重量轻,它也使用锁

我们也可以使用原子操作代替 GCD 信号量。在某些情况下,它会比 GCD Semaphore 更轻。

同步工具 - 原子操作

于 2011-02-27T22:00:46.947 回答
0

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

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

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

我想我会倒退并在这些区域使用另一种锁定技术。

于 2015-10-08T04:54:58.673 回答