170 похожих чатов

Я тут начал изучать корутины в котлине, и пока не

понимаю некоторые вещи. Вот когда мы запускаем корутину, т.е. вызываем какую-то suspend функцию, насколько я понимаю, во время компиляции из нее генерируется стейт-машина, где самый маленький execution unit - это код между двумя suspend вызовами, и если результат suspend-вызова еще не готов, то возвращаемся(сохраняя стейт, конечно). Но я не совсем понимаю, а кто заново вернется в эту функцию, когда результат suspend-функции будет готов? Там есть какой-то event-loop параллельно? И вообще, насколько я далек от правильного понимания?

16 ответов

5 просмотров

Да, в целом так. Корутины оборачиваются в таски и закидываются в executor, после исполнения которой, он опять закидывает таску с вызовом resume на корутине (вроде). Я детали подзабыл. https://stackoverflow.com/questions/53526556/how-do-kotlin-coroutines-work-internally https://kt.academy/article/cc-under-the-hood

Ilya-Starchenko Автор вопроса
Владислав Хакин
Да, в целом так. Корутины оборачиваются в таски и ...

Спасибо, стало яснее, т.е. в итоге получается такая картина: Мы запускаем в каком-то диспетчере корутину(Например, executor), вызываем suspend-функцию, доходим до блокирующего вызова, который возвращает courutine_suspend, записываем новый лэйбл, откуда нужно продолжить, и записываем в linked list сontinuation, идем наверх по стеку, оборачиваем этот linked list как таски, а диспатчер как-нибудь это все задиспатчит. Насчет последнего есть сомнения.

Ilya Starchenko
Спасибо, стало яснее, т.е. в итоге получается така...

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

Ilya Starchenko
Спасибо, стало яснее, т.е. в итоге получается така...

Не совсем так. Continuation никуда не складывается, он остаётся на руках у того, кто должен предоставить результат операции, и оттуда дёргается resume. Например, из коллбека. А вообще в @kotlin_lang наверное эффективнее такое спрашивать

Ilya-Starchenko Автор вопроса
Vladimir Petraković
Не совсем так. Continuation никуда не складывается...

Но resume же дергает сам диспатчер, значит они у него должны быть, нет?

Ilya Starchenko
Но resume же дергает сам диспатчер, значит они у н...

Нет, resume дёргает кто-то снаружи, и только там они и хранятся. Диспатчер не следит за всеми созданными continuation. Всё, что он может - обернуть их в свои, которые в resume кидают таску в этот диспатчер.

Ilya-Starchenko Автор вопроса
Vladimir Petraković
Нет, resume дёргает кто-то снаружи, и только там о...

Хм, не совсем понял, например, здесь, кто будет дергать resume: suspend fun main() = coroutineScope { repeat(1000) { launch(Dispatchers.IO) { Thread.sleep(200) val threadName = Thread.currentThread().name println("Running on thread: $threadName") }

Ilya Starchenko
Хм, не совсем понял, например, здесь, кто будет де...

Здесь вообще засыпания нет, Thread.sleep() очевидно просто блокирует тред на время ожидания

Ilya-Starchenko Автор вопроса
Vladimir Petraković
Здесь вообще засыпания нет, Thread.sleep() очевидн...

Хм, а думал, что вернется courutine_suspend, а потом кто-нибудь сделает resume и тогда уже поток уснет, но не суть, поменять sleep на какой-нибудь вызов с засыпанием.

Ilya Starchenko
Хм, а думал, что вернется courutine_suspend, а пот...

Ну да, так и есть. При засыпании возвращается маркер, а continuation остаётся на руках у этого кого-то. В это время диспатчер пойдёт выполнять следующую таску или спать, а этот кто-то может дёрнуть resume, когда посчитает нужным.

Ilya-Starchenko Автор вопроса
Vladimir Petraković
Ну да, так и есть. При засыпании возвращается марк...

Да, но в этом примере никто явно не вызывает resume, поэтому и не понятно, а кто этот кто-то.

Ilya Starchenko
Да, но в этом примере никто явно не вызывает resum...

Так это деталь реализации suspend функции, которая непосредственно засыпает. Всё зависит от того, что за операция. А в прикладном коде не должно быть нигде явного resume. Тут есть пример, как это может выглядеть: https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md#wrapping-callbacks

Ilya-Starchenko Автор вопроса
Vladimir Petraković
Так это деталь реализации suspend функции, которая...

Почитал, т.е. resume делается в каком-то колбэке suspend-функции, а сам диспетчер просто предоставляет свою реалзиацию continutaion и при вызове resume кидает задачу в executor, например. Поэтому, я так понимаю, и нельзя блокирующие операции в корутинах делать, потому что это лишь абстракция над колбэками.

Ilya Starchenko
Почитал, т.е. resume делается в каком-то колбэке s...

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

Ilya-Starchenko Автор вопроса
Vladimir Petraković
Ну не совсем, зависит от диспатчера. IO например с...

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

Похожие вопросы

Обсуждают сегодня

Если у меня есть такой класс: Object = {} function Object:new(a_name, a_transform, a_color, a_mesh, a_material, a_shader, a_textures) local private = {} private.n...
Cuarno Vile
4
я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
зачем же переименовывать ? чтобы кол-во участников возросло или вдруг IBM от этого снова на свифте начнет кодить ? Я не понимаю что страшного в том что свифт гавно, если это т...
Oleh Nerzh
10
здравствуйте. совершаю вот такую вещь: strcpy(line, (char)current_number); где current number — неподписанный шорт, line — массив чаров. ругань следующая: main.c:29:30: error...
Roberto's Ширгозиев
13
@MrMiscipitlick А можешь макрос написать, который будет вычислять смещение относительно переданных меток? Просто .label1-.label2, и вернуть значение.
КТ315
35
А еще в перле можно уже @arr1 + @arr2?
Sergei Zhmylove
53
Добрый день! Подскажите, пожалуйста: какими компетенциями нужно обладать, чтобы претендовать на работу эрланг (отдельная благодарность, если про элексир тоже подскажете) разр...
via ☸️ led
20
Всем привет. Ребят подскажите пожалуйста. Вопрос по дизасемблировани. Начну с начала. У меня есть скомпилированная программа на ГО (я разработчик) - в ней есть защита лицензии...
Zloy
11
Можно попросить небольшое ревью кода? Тут немнога, я ничего интереснее не придумал, чем написать аналог tree в качестве практики с cmake. https://github.com/hrimov/tree-unix/...
Andrew Hrimov
11
Привет всем. появился вопрос. Разрабатываю сайт, в данный момент он запущен. Хостинг beget. Добавляю на сайт яндекс метрику с помощью полей client-settings (взято отсюда http...
Andrew
2
Карта сайта