Я пытаюсь придумать лучший способ структурировать приложение Cocoa, которое по сути является параллельным менеджером загрузок. Есть сервер, с которым общается приложение, пользователь составляет большой список вещей, которые нужно развернуть, и приложение обрабатывает этот список. (Он не использует HTTP или FTP, поэтому я не могу использовать систему загрузки URL; я буду говорить через сокетные соединения.)
Это в основном классическая модель «производитель-потребитель». Хитрость в том, что количество потребителей фиксировано, и они постоянны. Сервер устанавливает строгое ограничение на количество одновременных подключений, которые могут быть открыты (хотя обычно это как минимум два), а открытие новых подключений стоит дорого, поэтому в идеальном мире те же N подключений открыты на протяжении всего срока службы приложения.
Одним из способов решения этой проблемы может быть создание N потоков, каждый из которых будет "владеть" соединением и ожидать очереди запросов, блокируя, если она пуста. Поскольку количество подключений никогда не будет огромным, это не является необоснованным с точки зрения фактической загрузки системы. Но концептуально кажется, что Какао должен предложить более элегантное решение.
Кажется, я мог бы использовать NSOperationQueue
и позвонить setMaxConcurrentOperationCount:
с указанием количества соединений. Затем я просто помещаю запросы на загрузку в эту очередь. Но в этом случае я не уверен, как самим управлять соединениями. (Просто поместите их в стек и положитесь на очередь, чтобы убедиться, что я не перегружен / недостаточно загружен? Добавьте семафор диспетчеризации вместе со стеком?)
Теперь, когда мы находимся в дивном новом мире Центральная диспетчерская служба , это открывает какие-то другие способы решения этой проблемы? На первый взгляд, это не похоже на то, что флагманская способность GCD динамически масштабировать параллелизм (и упомянутая в рекомендациях Apple по Изменение реализаций «производитель-потребитель» ) на самом деле мне не помогает. Но я только поцарапал поверхность чтения об этом.
EDIT:
В случае, если это имеет значение: да, я планирую использовать асинхронные / неблокирующие API сокетов для фактической связи с сервером. Таким образом, сам ввод / вывод не обязательно должен быть в отдельном потоке (ах). Я просто обеспокоен механикой постановки в очередь на работу и (безопасно) распределяю ее по соединениям, когда они становятся доступными.