Rhy*_*man 16 macos multithreading producer-consumer grand-central-dispatch ios
在Apple的并发编程指南的迁移远离线程部分中,有
改变生产者 - 消费者实现,声称可以使用GCD简化典型的多步骤pthread互斥+条件变量实现.
使用调度队列,您可以将生产者和消费者实现简化为单个调用:
dispatch_async(queue, ^{
// Process a work item.
});
Run Code Online (Sandbox Code Playgroud)
当您的生产者要完成工作时,它所要做的就是将该工作添加到队列中并让队列处理该项目.
生产者 - 消费者问题也被称为有界缓冲问题,但上面没有提到缓冲区,它的边界或消费者,更不用说阻止生产者和消费者以避免过度/不足的运行.
这怎么可能是一个有效的解决方案?
小智 23
在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 …];
});
}
Run Code Online (Sandbox Code Playgroud)
生产者可以放置与其可以生成的数据一样多的消费者任务.但是,这并不意味着GCD将以相同的速率启动消费者任务.GCD使用操作系统信息来控制根据当前系统负载执行的任务量.生产者本身没有受到限制,在大多数情况下,它不一定是因为GCD的固有负载平衡.
如果实际需要限制生产者,一个解决方案是拥有一个主服务器,该主服务器将调度n个生产者任务并让每个消费者通知主服务器(通过在消费者完成其工作之后调度的任务)它已经结束,其中如果主人将派遣另一个生产者任务.或者,消费者本身可以在完成时调度生产者任务.
具体回答您已解决的问题:
Producer-Consumer问题也称为Bounded-Buffer问题,但上面没有提到缓冲区
不需要共享缓冲区,因为使用者是Objective-C块,它会自动捕获它们引用的数据.
它的约束
GCD根据当前系统负载限制调度任务的数量.
或消费者
消费者是派遣到GCD队列的任务.
更不用说阻止生产者和消费者,以避免过度/不足
因为没有共享缓冲区,所以不需要阻塞.由于每个使用者都是一个Objective-C块,通过Objective-C块上下文捕获机制捕获生成的数据,因此消费者和数据之间存在一对一的关系.
| 归档时间: |
|
| 查看次数: |
4454 次 |
| 最近记录: |