苹果文档的GCD生产者 – 消费者解决scheme错误?

在Apple的“并发编程指南”的“从线程迁移”一节中,有
改变生产者 – 消费者实现 ,它宣称使用GCD可以简化典型的多步骤线程互斥+条件variables实现。

通过调度队列,可以将生产者和消费者实现简化为一个调用:

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

当您的生产者完成工作时,所要做的就是将该工作添加到队列中,让队列处理该项目。

生产者 – 消费者问题也被称为有界缓冲区问题,但是上面没有提到缓冲区,其边界或消费者,更不用说阻止生产者和消费者,以避免过度/不足的运行。

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

在苹果公司的文件中描述的解决scheme:

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

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

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

如果实际需要扼制生产者,一个解决scheme是有一个主人派遣n个生产者任务,并让每个消费者通知主人(通过在消费者完成其工作之后分派的任务)它已经结束,其中大师会派遣另一个生产者任务。 或者,消费者本身可以在完成后派遣生产者任务。

具体回答你已经解决的项目:

生产者 – 消费者问题也被称为有界缓冲区问题,但上面没有提到缓冲区

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

其约束

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

或消费者

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

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

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