ios - Apple doc的GCD Producer-Consumer解决方案错了吗?

标签 ios multithreading macos grand-central-dispatch producer-consumer

在 Apple 的并发编程指南的 Migrating Away from Threads 部分,有
Changing Producer-Consumer Implementations ,它声称可以使用 GCD 简化典型的多步 pthread 互斥 + 条件变量实现。

With dispatch queues, you can simplify the producer and consumer implementations into a single call:

dispatch_async(queue, ^{
  // Process a work item.
});

When your producer has work to be done, all it has to do is add that work to a queue and let the queue process the item.

Producer-Consumer 问题也称为 Bounded-Buffer 问题,但上面没有提到缓冲区、其边界或消费者,更不用说阻塞生产者和消费者以避免运行过度/不足。

这怎么可能是一个有效的解决方案?

最佳答案

在该 Apple 文档中描述的解决方案中:

  1. 没有缓冲区,因为不需要缓冲区;
  2. 系统负载是界限;
  3. 消费者是任务。

假设您有多个生产者和消费者,生产者将数据放在一个共享缓冲区中,而消费者则从该共享缓冲区中读取数据。信号量或监视器用于同步对共享缓冲区的访问,并且缓冲区大小是固定的,以便根据数据的消耗速率限制正在生成的数据量,从而限制生产者。

在 Grand Central Dispatch 下,消费者是指派给队列的任务。由于任务是 Objective-C block ,生产者不需要缓冲区来告诉消费者它应该处理的数据:Objective-C block 自动捕获它们引用的对象。

例如:

// Producer implementation
while (…) {
    id dataProducedByTheProducer;

    // Produce data and place it in dataProducedByTheProducer
    dataProducedByTheProducer = …;

    // Dispatch a new consumer task
    dispatch_async(queue, ^{
        // This task, which is an Objective-C block, is a consumer.
        //
        // Do something with dataProducedByTheProducer, which is
        // the data that would otherwise be placed in the shared
        // buffer of a traditional, semaphore-based producer-consumer
        // implementation.
        //
        // Note that an Objective-C block automatically keeps a
        // strong reference to any Objective-C object referenced
        // inside of it, and the block releases said object when
        // the block itself is released.

        NSString *s = [dataProducedByTheProducer …];
    });
}

生产者可以放置与它可以生产的数据一样多的消费者任务。然而,这并不意味着 GCD 将以相同的速率触发消费者任务。 GCD 使用操作系统信息来控制根据当前系统负载执行的任务量。生产者本身没有受到限制,而且在大多数情况下,它不必因为 GCD 的内在负载平衡而受到限制。

如果确实需要限制生产者,一个解决方案是让一个 master 分派(dispatch) n 个生产者任务,并让每个消费者通知 master(通过在消费者完成后分派(dispatch)的任务它的工作)它已经结束,在这种情况下,主人将 dispatch 另一个生产者任务。或者,消费者本身可以在完成后分派(dispatch)生产者任务。

具体回答您已解决的问题:

The Producer-Consumer problem is also known as the Bounded-Buffer problem, yet the above makes no mention of a buffer

不需要共享缓冲区,因为消费者是 Objective-C block ,它会自动捕获它们引用的数据。

its bound

GCD 根据当前系统负载限制分派(dispatch)任务的数量。

or the consumer

消费者是指派给 GCD 队列的任务。

let alone blocking the producer & consumer in order to avoid over/under runs

因为没有共享缓冲区,所以不需要阻塞。由于每个消费者都是一个 Objective-C block ,通过 Objective-C block 上下文捕获机制捕获生成的数据,因此消费者和数据之间存在一对一的关系。

关于ios - Apple doc的GCD Producer-Consumer解决方案错了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7792074/

相关文章:

java - 检查和控制实际并行运行的应用程序线程数

linux - 处理时如何传递+读取参数| (管道)?

xcode - OpenGL深度问题

python - 在 mac 中使用 python 为 safari 浏览器设置 selenium

ios - AudioKit iOS 设置输入和输出设备

ios - iOS 上使用 Unity 5 的 Google Cardboard 视频纹理

ios - 显示来自 viewDidLoad 的警报消息

python - 如何设计多线程GUI网络应用程序?

objective-c - 对类和对象 iVar 感到困惑

c - 为什么多个线程得到相同的 "tid?"