Pull to refresh

Comments 29

>> Причем, пока getImage выполняется в выделенном пуле потоков IO, главный поток свободен и может взяться за любую другую задачу!

Ну бред же.

Этот «главный поток» есть недоделанное детище ведро-архитекторов. Все остальные о таком чуде просто не знают (ибо вредные вещи им просто не нужны).

На самом деле поток исполнения блокируется до получения результата. А как там при этом перераспределяются потоки операционной системы — это уже второстепенно. И даже скорее вредно отделять потоки оси от порождаемых виртуальных потоков исполнения кода, ибо всем новичкам будет казаться, что они написали «всё правильно», а на самом деле они видят виртуальную картинку, которую сочинители котлина вынуждены были сочинить из-за убогости ведра, под которое всё же приходится писать (ибо широко распространённое поделие).

В общем — тупо прячем под ковёр гнилые потроха ведроида с его дичайшей асинхронностью и смертью всего на свете из-за лени архитекторов (не захотели под UI выделить отдельный поток).

"Главный поток" — это общая черта любых платформ GUI, а не только Андроида… Как минимум, он присутствует в WINAPI, XLib, WinForms (как следствие WINAPI), WPF, AWT, Qt...

>> это общая черта любых платформ GUI

Внимательно читаем о том, что такое windows, а потом смотрим на приведённый список аббревиатур и… В общем — не надо звонить, не обладая информацией. Затем читаем про систему X Window. Ну и доказываем, как же она подходит под «это общая черта любых платформ GUI».
А каких ещё примеров не хватает? Или вам здесь нужно статью из википедии скопировать?

Процитируйте ключевое на что вы ссылаетесь.
Бегло я не увидел на википедии ничего про потоки.


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


Замечу, что кроме Windows, Android, есть еще iOS/MacOS.

>> сколько не видел туториалов по иксам, там так же идет цикл событий

Читайте обзорную архитектуру. Иксы — это сервер. Он может быть вообще на другой стороне земли. Пояснять далее, почему на другой стороне земли будет отдельный поток?
Да, здесь всё безнадёжно…

Примеров GUI платформ, где не используется цикл событий в выделенном под него потоке.

Сервер иксов да, а клиент?


Вы сейчас сравниваете внутреннюю кухню сервера иксов с тем как работает клиент.
Апельсины с помидорами не очень сравниваются.

Всё со всем можно сравнить. И иксы отлично вписываются в данную тему. Но некоторые почему-то считают, что можно кодить только в одном единственном стиле, когда один глупый программист может повесить всю систему.

О какой "всей системе" речь? "Главный поток" в Андроиде свой собственный для каждого приложения. И повесить глупый программист может только свою собственную программу.

На самом деле поток исполнения блокируется до получения результата.

Он действительно свободен. иначе бы у вас интерфейс завис.
По сути тот код передает исполнение в поток из пула Dispatchers.IO.
Потом управление передается в Dispatchers.Main, этот диспатчер по сути оберка над runOnUiThread процитированным выше.
Все довольно просто.

Кто свободен? Читайте внимательно википедию про «текущий поток исполнения».

Интерфейс виснет от кривого архитектурного решения в ведроиде — UI ждёт, пока неграмотный программист закончит выполнять неэффективно написанную процедуру.

Читайте внимательно код, и что в каком потоке выполняется.


Отсылок на википедию от вас уже достаточно.
А по делу, как не было, так и нет.
одни нападки.

Интересно, что Издательский дом предпочитает изобретать свою терминологию «корутины» вместо устоявшийся "Сопрограммы" :) Боюсь покупать книги такого издательства с необычными терминами — куплю и ничего не пойму.
Всё-таки речь идёт про Kotlin. А в сообществе Kotlin слово «корутины» вполне общепринято и встречается чаще, чем «сопрограммы».
Спасибо за ответы. Но ведь каждое сообщество хочет расширяться, хочет чтобы его ЯП стал еще более популярным. А каждый дублирующий термин может создаь проблему для понимания новичком в этом сообществе. В статье при первом появлении такого термина можно написать «корутины (сопрограммы)».
С наилучшими пожеланиями сообществу Kotlin. (Я совершенно искренне).
А вот у меня такой вопрос: вот есть код из статьи:
launch(Dispatchers.Main) {
    val image = withContext(Dispatchers.IO) { getImage() } // контекст IO
    imageView.setImageBitmap(image) // контекст Main
}


Почему для I/O операций необходимо указывать свой контекст? Разве такой код в Android не будет работать/что-то заблокирует?
launch(Dispatchers.Main) {
    val image = getImage() // контекст Main, но это I/O операция
    imageView.setImageBitmap(image) // контекст Main
}


Если getImage() — это метод асинхронного ввода-вывода, разве он не приостановится при выполнении чтения как любая другая асинхронная функция в контексте main? Или это какой-то задел для мультиплатформы или типа того?

Так можно делать, чтобы ограничить число параллельных блокирующих IO операций.


Иначе:


  • Блокирующие операции могут остановить один из общих потоков (т.е. приложение не сможет выполнить простую операцию просто потому, что все потоки ждут, или другими словами — процессор свободен, однако программа не может его использовать). Следовательно — все блокирующие вещи должны быть отдельно.
  • Много IO операций с диском всё равно не смогут выполняться параллельно (дисков-то не так много), значит желательно ограничить параллелизм, чтобы:
    • Соседние операции не мешали друг другу
    • Не создавать много потоков, каждый из которых кушает около 2 Мб (для стандартной Java).

Следовательно, всё блокирующее IO взаимодействие лучше выделить в отдельный пул потоков — Dispatchers.IO


Аналогичная идея есть у .Net с SynchronizationContext.

Следовательно, всё блокирующее IO взаимодействие лучше выделить в отдельный пул потоков — Dispatchers.IO

В этом собственно и был вопрос: а стоит ли метод асинхронного ввода-вывода исполнять в контексте "блокирующего IO взаимодействия"?

В теории, блокирующие I/O операции вообще не должны использоваться, и вместо них необходимо использовать их неблокирующие аналоги. А для операций, которых не имеют таких аналогов (не приходит ничего на ум) — использовать Dispatcher.IO.
Хотя вот тоже спорно — стоило ли вообще делать отдельный диспетчер для ввода-вывода, если Default справляется точно так же? Только ради ограничения по количеству параллельно выполняемых операций? Но в Default по идее также должно стоять такое же ограничение по количеству параллельно выполняющихся блокирующих потоков…
Авторы языка решили, что Dispatcher.IO почему-то удобнее именно для IO, хотя Default работает полностью идентично. Причина такого решения абсолютно непонятна. Точнее — авторы не захотели её пояснять в доках по API.

В целом имеем полное копирование истории с ведроидом — такие же неполноценные доки без пояснения выбранных архитекторами концепций.
Sign up to leave a comment.