在该 Apple 文档中描述的解决方案中:
- 没有缓冲区,因为不需要缓冲区;
- 系统负载是有界的;
- 消费者是任务。
假设您有多个生产者和消费者,生产者将数据放置在共享缓冲区中,消费者从该共享缓冲区读取数据。信号量或监视器用于同步对共享缓冲区的访问,并且缓冲区大小是固定的,以便根据消耗的速率限制正在生成的数据量,从而限制生产者。
在 Grand Central Dispatch 下,消费者是调度到队列的任务。由于任务是 Objective-C 块,因此生产者不需要缓冲区来告诉消费者它应该处理的数据:Objective-C 块会自动捕获它们引用的对象。
例如:
// 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 固有的负载平衡,因此不必受到限制。
如果确实需要限制生产者,一种解决方案是拥有一个可以调度的主机n生产者任务,并让每个消费者通知主机(通过消费者完成其工作后调度的任务)它已经结束,在这种情况下,主机将调度另一个生产者任务。或者,消费者本身可以在完成后调度生产者任务。
具体回答您所解决的问题:
生产者-消费者问题也称为有界缓冲区问题,但上面没有提到缓冲区
不需要共享缓冲区,因为消费者是 Objective-C 块,它会自动捕获它们引用的数据。
它的界限
GCD根据当前系统负载限制调度任务的数量。
或消费者
消费者是调度到 GCD 队列的任务。
更不用说为了避免超载/欠载而阻塞生产者和消费者了
由于没有共享缓冲区,因此不需要阻塞。由于每个消费者都是一个 Objective-C 块,通过 Objective-C 块上下文捕获机制捕获生成的数据,因此消费者和数据之间存在一对一的关系。