Кто отвечает за приостановку и продолжение сопрограмм? - PullRequest
9 голосов
/ 24 мая 2019

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

Предположение: Общая идеяЯ имею в виду асинхронное программирование:

Когда мы запускаем операцию блокировки (сетевой вызов, чтение из БД / файла), мы можем делегировать ее потоку (ям) ядра, которые сохранят поток (и) нашего приложения.) бесплатно для других работ.Поток ядра ожидает выполнения задания и вызывает обратный вызов для потока приложения при каждом выполнении задания.

Сопрограммы: Я читал о Kotlin Coroutines в последний разнесколько дней.Я думаю, что концепция мудрых сопрограмм не зависит от языка.Вопрос, который я получаю:

Как происходит suspension и continuation для сопрограммы.Сопрограммы - это не потоки (которым ОС предоставляет фрагмент процессора), они tasks, которые будут запланированы для выполняемого потока.

Кто продолжает искать программу в процессе выполнения и говорит:эта сопрограмма достигла точки подвеса, и ее следует извлечь из нити.Другая сопрограмма, которую необходимо возобновить с continuation, должна быть запланирована в потоке.Что касается того, что я прочитал о Java Fibers, то это будет сделано Fiber Scheduler, похоже ли это в Котлине?

Спасибо заранее за помощь.

1 Ответ

5 голосов
/ 24 мая 2019

Подвеска Coroutine полностью явная и первоклассная. Это происходит, когда вы вызываете suspendCoroutine() или suspendCancellableCoroutine(), передавая блок, который получает продолжение в качестве параметра.

Блок может делать с объектом продолжения все, что хочет, и когда кто-то где-то вызывает continuation.resume(resultValue(), он возобновляет работу. Поток, с которого он возобновляет работу, изначально является потоком, который вызывает resume(), но логика внутри resume немедленно делегирует ответственному диспетчеру, который затем обычно передает возобновление другому потоку или пулу потоков.

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

Вы также можете просмотреть конкретный пример в коде , который демонстрирует скрытое использование suspendCoroutine и coroutine.resume() без слоя, который добавляет к нему Диспетчер.


Кстати, вы никогда не делегируете блокирующие операции «потокам ядра», чтобы сделать их неблокирующими. Асинхронные операции не блокируют ни один поток. На низком уровне, например, есть механизм селектора , который получает события от операций ввода-вывода, когда они завершаются. Он работает так же, как цикл обработки событий в потоке GUI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...