Ответ 1
В решении, описанном в этом документе 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 заданий производителя, и каждый потребитель уведомляет мастера (через задание, отправленное после того, как потребитель завершил свое задание), что он закончился, и в этом случае мастер отправил бы другую задачу производителя. В качестве альтернативы, потребитель сам по себе может отправить задание производителя.
В частности, отвечая на адреса, которые вы адресули:
Проблема "Продюсер-потребитель" также известна как проблема Bounded-Buffer, но выше не упоминается буфер
Общий буфер не нужен, потому что потребители представляют собой Objective-C блоки, которые автоматически захватывают данные, которые они ссылаются.
его граница
GCD ограничивает количество отправленных задач в соответствии с текущей загрузкой системы.
или потребителя
Потребители - это задачи, отправленные в очереди GCD.
не говоря уже о блокировании производителя и потребителя, чтобы избежать превышения/ниже пробега
Нет необходимости блокировать, поскольку нет общего буфера. Поскольку каждый потребитель является блоком Objective-C, который захватывает полученные данные с помощью механизма захвата контекста блока Objective-C, существует взаимно-однозначное отношение между потребителем и данными.