Многопоточность: лучший способ уведомлений о потоках с потерями в Swift? - PullRequest
1 голос
/ 13 июля 2020
• 1000 отправка следующего пакета параметров. Например, при отключении аудиоузла основной поток должен дождаться следующего цикла, когда будет получена команда отключения и узел отключится.

Иногда для основного потока важно дождаться команда выполняется полностью, но в других случаях это не важно, поэтому никто не может прослушивать событие syn c. Отсюда сценарий «с потерями».

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

Не могу придумать способов использования семафора для этой задачи. Есть ли какие-нибудь канонические способы добиться этого? Похоже, что Java s notifyAll() работает именно так, если да, то какой механизм синхронизации используется за notifyAll()?

Edit: думал, есть ли такая вещь, как «пришлите мне семафор в очереди, и я сигнализирую "? Кажется слишком сложным, но теоретически это может сработать. Есть ли более простые инструменты для той же задачи?

1 Ответ

1 голос
/ 13 июля 2020

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

Основная проблема заключается в том, что если приложение слишком долго блокирует основной поток, у вас есть плохой UX (где кажется, что приложение зависает), и вы рискуете, что ваше приложение будет убито процессом сторожевого пса. Поэтому я бы не советовал использовать семафоры (или любые другие подобные механизмы), чтобы иметь основной поток wait для чего-то из вашего контроллера звукового движка.

Так, например, предположим, что основной поток хочет сообщить звуковой движок, чтобы приостановить воспроизведение, но вы хотите, чтобы пользовательский интерфейс «ждал» подтверждения и обработки. Вместо фактического ожидания мы бы настроили некоторый асинхронный шаблон, в котором основной поток уведомляет звуковой движок о том, что он хочет, чтобы он приостановился, а затем аудиоконтроллер уведомит основной поток, когда этот запрос был обработан с помощью некоторого механизма обратного вызова (например, через шаблон протокола делегата, закрытие обработчика завершения и т. д. c.). Если вам нужно предотвратить взаимодействие с пользователем в течение промежуточного времени, вы должны отключить контроллер и использовать какой-нибудь UIActivityIndicatorView (например, счетчик) или что-то в этом роде, что-то, что будет удалено при вызове обработчика завершения.

Вы использовали термин «с потерями», но это обычно означает, что вы не возражаете, если запрос потеряется. Но я предполагаю, что это не совсем так. Я предполагаю, что вы на самом деле не хотите, чтобы запрос был потерян, а просто то, что основной поток не заботится об ответе, будучи уверенным, что аудиоконтроллер доберется до него, когда сможет. В этом случае вы, вероятно, все же передадите такой запрос аудиоконтроллеру механизм обратного вызова, но основной поток просто не воспользуется им.

Теперь, если у вас есть последовательность команд, которая если вы хотите, чтобы звуковой движок обрабатывался по порядку, тогда аудиоконтроллер может иметь частную внутреннюю очередь для этих запросов, где вы можете настроить его так, чтобы он не запускал последующие запросы до тех пор, пока не завершатся предыдущие. Основной поток не должен беспокоиться о том, обработан ли требуемый аудио цикл. Он должен просто отправлять любые подходящие запросы, а аудиоконтроллер должен обрабатывать их в желаемом порядке / времени.

...