Apple doc的GCD Producer-Consumer解决方案错了吗? [英] Apple doc's GCD Producer-Consumer solution wrong?

查看:119
本文介绍了Apple doc的GCD Producer-Consumer解决方案错了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Apple的并发编程指南的迁移远离线程部分,有
更改生产者 - 消费者实现,声称典型的多步骤pthread互斥+条件变量实现可以使用GCD简化。

In the Migrating Away from Threads section of Apple's Concurrency Programming Guide, there is
Changing Producer-Consumer Implementations, which claims that the typical multistep pthread mutex + condition variable implementation can be simplified using GCD.


使用调度队列,您可以将生产者和消费者
实现简化为一次调用:

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问题,但上面没有提到缓冲区,它的界限或消费者,更不用说阻止生产者和消费者,以避免过度/不足。

The Producer-Consumer problem is also known as the Bounded-Buffer problem, yet the above makes no mention of a buffer, its bound or the consumer, let alone blocking the producer & consumer in order to avoid over/under runs.

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

How can this be a valid solution?

推荐答案

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

In the solution decribed at that Apple document:


  1. 没有缓冲区,因为不需要缓冲区;

  2. 系统加载是绑定;

  3. 消费者是任务。

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

Say you have multiple producers and consumers, producers place data in a shared buffer and consumers read data from that shared buffer. A semaphore or monitor is used to synchronise access to the shared buffer, and the buffer size is fixed so as to limit the amount of data that are being produced according to the rate they’re being consumed, hence throttling the producer.

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

Under Grand Central Dispatch, consumers are tasks dispatched to a queue. Since tasks are Objective-C blocks, a producer doesn’t need a buffer to tell a consumer about the data it should process: Objective-C blocks automatically capture objects they reference.

例如:

// 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的内在负载平衡。

The producer may place as many consumer tasks as data it can produce. However, this doesn’t mean that GCD will fire the consumer tasks at the same rate. GCD uses operating system information to control the amount of tasks that are executed according to the current system load. The producer itself isn’t throttled, and in most cases it doesn’t have to be because of GCD’s intrinsic load balancing.

如果实际需要限制生产者,一个解决方案是让一个主服务器调度 n 生产者任务并让每个消费者通知主服务器(通过在消费者完成其工作之后调度的任务)它已经结束,在这种情况下master会调度另一个生产者任务。或者,消费者本身可以在完成时调度生产者任务。

If there’s actual need to throttle the producer, one solution is to have a master that would dispatch n producer tasks and have each consumer notify the master (via a task that’s dispatched after the consumer has finished its job) that it has ended, in which case the master would dispatch another producer task. Alternatively, the consumer itself could dispatch a producer task upon completion.

专门回答您已解决的项目:

Specifically answering the items you’ve addressed:

Producer-Consumer问题也称为Bounded-Buffer问题,但上面没有提到缓冲区

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

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

A shared buffer isn’t needed because consumers are Objective-C blocks, which automatically capture data that they reference.


其界限

its bound

GCD根据当前系统负载限制调度任务的数量。

GCD bounds the number of dispatched tasks according to the current system load.


或消费者

or the consumer

消费者是调度到GCD队列的任务。

Consumers are the tasks dispatched to GCD queues.


更不用说阻止生产者&消费者,以避免过度/不足的运行

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

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

There’s no need for blocking since there’s no shared buffer. As each consumer is an Objective-C block capturing the produced data via the Objective-C block context capturing mechanism, there’s a one-to-one relation between consumer and data.

这篇关于Apple doc的GCD Producer-Consumer解决方案错了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆