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

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

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

16 ответов

18 просмотров

Да, в целом так. Корутины оборачиваются в таски и закидываются в 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 например с...

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

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта