在 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 文档中描述的解决方案中:
- 没有缓冲区,因为不需要缓冲区;
- 系统负载是界限;
- 消费者是任务。
假设您有多个生产者和消费者,生产者将数据放在一个共享缓冲区中,而消费者则从该共享缓冲区中读取数据。信号量或监视器用于同步对共享缓冲区的访问,并且缓冲区大小是固定的,以便根据数据的消耗速率限制正在生成的数据量,从而限制生产者。
在 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/