Неверное решение GCD производителя-потребителя Apple doc?

В разделе «Миграция с нитей» руководства по параллелизму Apple, существует
Изменение Producer-Consumer Implementations , в котором утверждается, что типичная многоступенчатая реализация переменных переменных mutex + pthread может быть упрощена с использованием GCD.

С очередями отправки вы можете упростить реализацию производителя и потребителя в один вызов:

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

Когда ваш продюсер должен работать, все, что ему нужно сделать, это добавить эту работу в очередь и позволить очереди обрабатывать элемент.

Проблема «Продюсер-потребитель» также известна как проблема Bounded-Buffer, но в вышеизложенном не упоминается буфер, его привязка или потребитель, не говоря уже о блокировании производителя и потребителя, чтобы избежать превышения / под управлением.

Как это может быть правильным решением?

В решении, описанном в этом документе Apple:

  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.

Если существует настоятельная необходимость дросселировать производителя, одно решение состоит в том, чтобы иметь мастер, который будет отправлять n заданий производителя, и каждый потребитель уведомляет мастера (через задание, отправленное после того, как потребитель завершил свою работу), что он закончился, в котором если мастер отправит другую задачу производителя. В качестве альтернативы, потребитель сам может отправить задание производителя после его завершения.

В частности, отвечая на вопросы, которые вы указали:

Проблема «Продюсер-потребитель» также известна как проблема Bounded-Buffer, но выше не упоминается буфер

Общий буфер не нужен, поскольку потребители являются блоками Objective-C, которые автоматически захватывают данные, которые они ссылаются.

его

GCD ограничивает количество отправленных задач в соответствии с текущей загрузкой системы.

или потребителя

Потребители – это задачи, отправленные в очереди GCD.

не говоря уже о блокировании производителя и потребителя, чтобы избежать превышения / под управлением

Блокировать не нужно, поскольку нет общего буфера. Поскольку каждый потребитель является блоком Objective-C, который захватывает полученные данные с помощью механизма захвата контекста Objective-C, между потребителем и данными существует взаимно однозначное отношение.

  • SpriteKit - остановка объектов наложения
  • Как использовать услугу с помощью IOBluetooth / CoreBluetooth?
  • Captive Wifi Popup: нажмите ссылку, чтобы открыть Safari
  • Справочные пути XCode Framework и сборка выходных каталогов
  • Обмен игровыми данными между клиентами iPhone / iPad / Mac OSX
  • USB-связь между iPad и Mac или ПК
  • Извлечь сервис и модель с помощью CoreData в Cocoapod
  • Xcode загружается в объекты OS X вместо объектов iOS
  • Найдите, если файл ipa 32 или 64-разрядный. (MacOS / Unix)
  • Swift 2 JSON POST запрос
  • Какой CGImageAlphaInfo мы должны использовать?
  • Interesting Posts

    Невозможно установить привязку (в: UITableView) с помощью переменной RxSwift asObservable ()

    Отображать многократное отображение RestKit, как?

    SQLite Out of Memory при подготовке инструкции insert

    __NSArrayM insertObject: atIndex:]; объект не может быть nil

    XMPPFramework – Как создать комнату MUC и пригласить пользователей?

    Нужно писать в файл, используя fopen в классе C ++ для проекта iOS

    Как декодировать звуковой буфер AAC в буфер PCM в iOS?

    Как остановить / отменить / приостановить / возобновить задачи в очереди GCD

    iPhone получает список всех SSID без частной библиотеки

    Как вы распространяете бета-приложения iOS в своей команде, не используя тестовый полет?

    Как запретить WKWebView неоднократно запрашивать разрешение на доступ к местоположению?

    iOS itunesconnect тестовая учетная запись для песочницы (недопустимый год)

    iphone UITable reloadRowsAtIndexPaths очень странная проблема

    Поиск NSString в NSMutableArray

    Swift – Как создать представление таблицы на основе данных, загруженных асинхронно?

    Давайте будем гением компьютера.