Как синхронизировать задачи в разных очередях отправки? - PullRequest
9 голосов
/ 27 июля 2011

Я новичок в очередях и у меня возникли некоторые проблемы при настройке следующей схемы.

У меня есть три задачи, которые нужно выполнить.

Задача A: Может выполняться только наглавная очередь, может выполняться асинхронно с задачей B, не может асинхронно работать с задачей C. Работает много, но выполняется довольно быстро.

Задача B: Может работать в любой очереди, может выполняться асинхронно с задачей A, не может работать асинхроннос заданием C. Работает редко, но занимает много времени.После этого требуется выполнение задачи C, но снова задача C не может работать асинхронно с задачей A.

Задача C: может выполняться в любой очереди.Невозможно выполнить асинхронно ни с задачей A, ни с задачей B. Работает редко и выполняется быстро.

Прямо сейчас у меня так:

Задача A отправляется в основную очередь с помощью последовательной очереди X(задача отправляется в последовательную очередь X для отправки задачи A в основную очередь).

Задача B отправляется в последовательную очередь X.

Задача C отправляется в основную очередь с помощью последовательного интерфейсаОчередь X, точно так же, как задача A.

Проблема здесь в том, что задача C иногда запускается одновременно с задачей B. Основная очередь иногда запускает задачу C в то же время, что последовательная очередь выполняет задачу B.

Итак, как я могу гарантировать, что задача B и задача C никогда не будут выполняться одновременно, при этом позволяя A и B запускаться одновременно и предотвращая одновременное выполнение A и C?Кроме того, есть ли простой способ убедиться, что они запускаются одинаковое количество раз?(чередование вперед и назад)

Ответы [ 3 ]

2 голосов
/ 27 июля 2011

Вы знаете, я думаю, что у меня была эта проблема на моем GRE, только А, В и С были Боб, Ларри и Сью, и все они работали в одном офисе.

Я считаю, что это можетрешаться с помощью комбинации последовательной очереди и семафора отправки.Если вы настроите единую очередь последовательной отправки и отправите в нее задачи B и C, вы гарантируете, что они не будут выполняться одновременно.Затем вы можете использовать диспетчерский семафор со счетчиком, установленным в 1, который совместно используется задачами A и C, чтобы гарантировать, что одновременно будет выполняться только один из них.Я описываю, как работает такой семафор, в моем ответе здесь .Возможно, вам придется изменить этот код для использования DISPATCH_TIME_FOREVER, чтобы задача A задерживалась перед отправкой, а не просто отбрасывалась в сторону, если C работает (аналогично для отправки C).

Таким образом, A и Bбудут работать в разных очередях (основной очереди и вашей последовательной очереди), поэтому они могут выполняться параллельно, но B и C не могут работать одновременно из-за их общей очереди, а A и C - из-за семафора.

Что касается балансировки нагрузки на А и С (то, что я предполагаю, что вы хотите сбалансировать), это, вероятно, будет зависеть от конкретного приложения и может потребовать некоторых экспериментов с вашей стороны, чтобы увидеть, как правильно чередовать действия безтратить циклы.Я также позаботился о том, чтобы вам действительно нужно было их чередовать равномерно, или если вы можете обойтись, если один работает немного больше другого.

0 голосов
/ 01 ноября 2011

Существует гораздо более простой способ, конечно, предполагая, что C всегда должен следовать за A и B, то есть иметь расписание A и B C в качестве обратных вызовов завершения для своих собственных операций (и иметь проверку C, чтобы убедиться, что она еще не запущенав случае, когда A и B оба просят, чтобы это произошло одновременно).Шаблон обратного вызова завершения (описанный на странице руководства dispatch_async) является очень мощным и отличным способом сериализации асинхронных операций, которые, тем не менее, должны быть связаны.

Где проблема A, B, C, D и E, где ADможет выполнять асинхронное выполнение, а E всегда должен выполняться в конце, группы рассылки являются лучшим решением, поскольку вы можете настроить E для запуска в качестве обратного вызова завершения для всей группы, а затем просто поместить AE в эту группу.

0 голосов
/ 27 июля 2011

Вы проверяли NSOperation для синхронизации своих операций? Вы можете обрабатывать зависимости там.

...