Здравствуйте, m2user, Вы писали:
M>>>По-видимому Executors.newVirtualThreadPerTaskExecutor — предполагаемое решение для обоих случаев. M>·>Это такой пример. Тут из треда который выполняет handle (которых уже может быть овердофига), запускается ещё два новых треда и ожидается их завершение. M>·>Покажи аналогичный код лучше. M>Async/await, как оно сделано в C#. Но конечно оно потребует и async версии readAllBytes.
Угу. И так по всему коду — всё потребует async версию.
M>>>Но разворачивать ExecutionException до IOException придется вручную M>·>Зачем? И почему _придётся_? M>Для реализации нетривиальной логики обработки IOException — либо обрабатывать внутри fetchURL, либо разворачивать ExecutionException до IOException.
Я не очень понимаю. Приведи пример. Для чего тебе требуется вынимать IOException? Если у тебя что-то работает в другом потоке, неважно виртуальном или реальном, то тебе нужно как-то передать исключение между потоками. Исключения обычно логгируют, да и всё.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, m2user, Вы писали:
M>·>Не совсем. Этот await не нужно протаскивать везде. M>·>Т.е. у тебя есть какой-то обычный бизнес-код с синхронным readAllBytes — и у него никакого Task/async нет. И join нужен только собственно чтобы дождаться результата от всех тредов. M>Это неполноценный асинхронный код, т.к. нет cancellation.
А зачем он везде в общем случае? Специальная конструкция как в CancellationToken не требуется.
M>Если реализовать cancellation (как я понимаю, применительно к IO в Java это делается через AsynchronousChannel), то будут Future (вместо Task). И в итоге можно получить тот же function coloring
Если у тебя есть какой-то сокет и ты хочешь прервать код, который на нём ждёт слишком долго, то поставь таймаут. Или если какое-то внешнее взаимодейсвтие, что сокет больше не нужен — закрой сокет. И т.п.
Т.е. какой-то универсальный cancellation не нужен.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Serginio1, Вы писали:
S>·>Я вопрос не понял. Тасков нет никаких с виртуальными потоками. S> Ну например в .Net уже и не найти синхронных методов.
Точнее количество методов удвоено — синхронный вариант и асинхронный.
S> Я так понимаю, что перед вызовом readAllBytes сохраняется стек, вызывается асинхронный метод по завершении которого возвращается стек и продолжение происходит с после readAllBytes. S> То есть компилятор должен знать что есть асинхронный readAllBytes?
Нет никакого специального асинхронного readAllBytes. Как я понял отсюда, он отдаёт задание на чтение байтов реальному глобальному jvm-треду "Read-Poller" и блокируется в ожидании результата. Блокировка позволяет отсоединить виртуальный тред (сохраняя стек) и положить его в очередь.
И компилятор тут непричём. Это просто детали реализации socket api.
S> Можно ли смешивать асинхронный код и виртуальные потоки?
Никакого особого магического асинхронного кода со всякими генерёнными конечными автоматами в java нет. Поэтому что ты хочешь смешивать неясно.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
·>Если у тебя есть какой-то сокет и ты хочешь прервать код, который на нём ждёт слишком долго, то поставь таймаут. Или если какое-то внешнее взаимодейсвтие, что сокет больше не нужен — закрой сокет. И т.п.
Где то в начале стека определилось, что не нужны дальнейшие вычисления. Как мне их все прервать по всему стеку?
и солнце б утром не вставало, когда бы не было меня
S>> Я так понимаю, что перед вызовом readAllBytes сохраняется стек, вызывается асинхронный метод по завершении которого возвращается стек и продолжение происходит с после readAllBytes. S>> То есть компилятор должен знать что есть асинхронный readAllBytes? ·>Нет никакого специального асинхронного readAllBytes. Как я понял отсюда, он отдаёт задание на чтение байтов реальному глобальному jvm-треду "Read-Poller" и блокируется в ожидании результата. Блокировка позволяет отсоединить виртуальный тред (сохраняя стек) и положить его в очередь. ·>И компилятор тут непричём. Это просто детали реализации socket api.
То есть это касается только сокетов?
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>·>И компилятор тут непричём. Это просто детали реализации socket api. S> То есть это касается только сокетов?
Весь io.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Serginio1, Вы писали:
S>·>Если у тебя есть какой-то сокет и ты хочешь прервать код, который на нём ждёт слишком долго, то поставь таймаут. Или если какое-то внешнее взаимодейсвтие, что сокет больше не нужен — закрой сокет. И т.п. S> Где то в начале стека определилось, что не нужны дальнейшие вычисления. Как мне их все прервать по всему стеку?
Можно пример?
Если ты в том же SemaphoreSlim вызывается async wait без cancellation token — как прервать?
Вообще cancellation ортогонален асинхронщине. Посмотри, там есть и синхронный wait с cancellation token.
Врочем, можно использовать thread.interrupt().
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
S>>·>Если у тебя есть какой-то сокет и ты хочешь прервать код, который на нём ждёт слишком долго, то поставь таймаут. Или если какое-то внешнее взаимодейсвтие, что сокет больше не нужен — закрой сокет. И т.п. S>> Где то в начале стека определилось, что не нужны дальнейшие вычисления. Как мне их все прервать по всему стеку? ·>Можно пример? ·>Если ты в том же SemaphoreSlim вызывается async wait без cancellation token — как прервать? ·>Вообще cancellation ортогонален асинхронщине. Посмотри, там есть и синхронный wait с cancellation token. ·>Врочем, можно использовать thread.interrupt().
Это конечно да!
Суть в том, что может быть цепочка асинхронных вызовов вплоть до рекурсии.
То есть внутри метода вызывает асинхронный метод и так далее
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>·>Если ты в том же SemaphoreSlim вызывается async wait без cancellation token — как прервать? S>·>Вообще cancellation ортогонален асинхронщине. Посмотри, там есть и синхронный wait с cancellation token. S>·>Врочем, можно использовать thread.interrupt(). S> Это конечно да! S> Суть в том, что может быть цепочка асинхронных вызовов вплоть до рекурсии. S>То есть внутри метода вызывает асинхронный метод и так далее
Т.е. у тебя должен быть специально написанный код, который предусматривает прерывание в предусмотренных местах. Неясно какое отношение это имеет к асинхронщине или многопоточке. Это ортогональные вещи.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
S>> Суть в том, что может быть цепочка асинхронных вызовов вплоть до рекурсии. S>>То есть внутри метода вызывает асинхронный метод и так далее ·>Т.е. у тебя должен быть специально написанный код, который предусматривает прерывание в предусмотренных местах. Неясно какое отношение это имеет к асинхронщине или многопоточке. Это ортогональные вещи.
Конечно! Обычно методы и принимают параметр System.Threading.CancellationToken https://learn.microsoft.com/ru-ru/dotnet/api/system.io.filestream.readasync?view=net-7.0
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>>>·>Весь io. S>>>Ну это понятно. Просто Tаsk это не только IO. S>·>Именно IO доставляет проблемы потокам. S> Не обязательно. Народ запускает кучу параллельных потоков для распараллеливания задач, сервера, причем используют примитивы синхронизации. S>С помощью Task можно решать кучу задач с помощь небольшого количества потоков.
Да ясен пень. Сабж как раз про то, что не нужно решать задачи с помощью Task, которому нужно специальные ключевые слова в язык, который требует от компилятора перекорёживать код, заставляет писать два варианта каждого метода, затрудняет понимание и отладку кода. Вместо этого можно просто иметь большое количество потоков.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
S>>>>Ну это понятно. Просто Tаsk это не только IO. S>>·>Именно IO доставляет проблемы потокам. S>> Не обязательно. Народ запускает кучу параллельных потоков для распараллеливания задач, сервера, причем используют примитивы синхронизации. S>>С помощью Task можно решать кучу задач с помощь небольшого количества потоков. ·>Да ясен пень. Сабж как раз про то, что не нужно решать задачи с помощью Task, которому нужно специальные ключевые слова в язык, который требует от компилятора перекорёживать код, заставляет писать два варианта каждого метода, затрудняет понимание и отладку кода. Вместо этого можно просто иметь большое количество потоков.
Нееее. Это частный метод с одним уровнем. Как правило таски это многоуровневые вложения.
Я не вижу особых проблем с async/await. А вот с виртуальными потоками вижу. То есть совместно с тасками их не применить.
Это просто оптимизация не асинхронного кода. Коего не так уж и много в том же C#.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>·>Да ясен пень. Сабж как раз про то, что не нужно решать задачи с помощью Task, которому нужно специальные ключевые слова в язык, который требует от компилятора перекорёживать код, заставляет писать два варианта каждого метода, затрудняет понимание и отладку кода. Вместо этого можно просто иметь большое количество потоков. S> Нееее. Это частный метод с одним уровнем. Как правило таски это многоуровневые вложения.
Нет. async/await — это виртуальные треды для бедных.
S> Я не вижу особых проблем с async/await. А вот с виртуальными потоками вижу. То есть совместно с тасками их не применить.
Тут уже несколько примеров приводили с Future и StructuredTaskScope.
S>Это просто оптимизация не асинхронного кода. Коего не так уж и много в том же C#.
Нет. Это возможность запускать асинхронно синхронный код c io и синхронизированный примитивами синхронизации код.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Serginio1, Вы писали:
S> ·>Т.е. у тебя должен быть специально написанный код, который предусматривает прерывание в предусмотренных местах. Неясно какое отношение это имеет к асинхронщине или многопоточке. Это ортогональные вещи. S> Конечно! Обычно методы и принимают параметр System.Threading.CancellationToken
Неясно какое отношение это имеет к асинхронщине или многопоточке. Это ортогональные вещи.
Здравствуйте, ·, Вы писали:
·>Ну как бы не совсем. Зелёные потоки — это все потоки VM работают на одном реальном потоке и всё. А тут эти треды можно шедулить как душе угодно.
Раньше так не умели просто, а сейчас научились. Если бы во времена первой джавы умели скедулить как хотят, то это было бы сделано сразу.
Здравствуйте, ·, Вы писали:
S>>Это просто оптимизация не асинхронного кода. Коего не так уж и много в том же C#. ·>Нет. Это возможность запускать асинхронно синхронный код c io и синхронизированный примитивами синхронизации код.
Я тебе приводил пример асинхронных примитвов синхронизации. То есть ты повторил мои же выводы
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, ·, Вы писали:
S>> ·>Т.е. у тебя должен быть специально написанный код, который предусматривает прерывание в предусмотренных местах. Неясно какое отношение это имеет к асинхронщине или многопоточке. Это ортогональные вещи. S>> Конечно! Обычно методы и принимают параметр System.Threading.CancellationToken ·>Неясно какое отношение это имеет к асинхронщине или многопоточке. Это ортогональные вещи.