Здравствуйте, alex_public, Вы писали:
_>Согласен, что в случае JS раньше (сейчас то уже есть Web Workers API) было такое ограничение и единственным средством организации параллельного выполнения в JS были асинхронные вызовы (не важно обёрнутые в сопрограммы или же просто в виде коллбэков). Но в наше время уже даже в JS такого не требуется.
Ты наверное не очень много программировал в браузере. Одна из типичных задач которая там необходима — этотнекоторый аналог await Task.Yield(), что б браузер расчехлился в некоторых аспектах. Сейчас такого нужно меньше. Есть просто только асинхронные апи, поэтому выбора то нет.
Насчет WebWorker API — это именно для изолированного не связанного с DOM кода. Там же сериализация в полный рост. В общем вещь то не плохая, но специфическая и стоит она не мало.
_>А вот для этих целей запуск отдельных потоков (с использованием внутри них синхронных операций) точно будет правильнее. Не нужен тут ни асинхронный ввод-вывод, ни сопрограммы.
Но если данные 95% доступны — почему бы методу не быть async ValueTask? Да и вообще,почему бы и нет? async/await / TPL — это же ведь еще и контракт. Если тебе надо подождать эти данные — ты здаешь где ждать. Не надо внезапно реализовывать эту функцию, или о боже, прокидывать этот асинхронный результат через IPC. Видишь метод — понятно,что он может исполняться значимое время и в том числе поэтому он асинхронный. Внутри же он волен хоть поток создать, хоть поставить 10 задач в пул.
_>Я тут говорил как раз не про задачи, которые плохо распараллеливаются. А скорее про задачи, для распараллеливания которых правильнее применять более адекватные инструменты.
Где эти адекватные инструменты? Куда не глянь, гомора одна с содомией. Включая дотнет. Просто, даже если откинуть TPL — то асинк методы дают довольно внятный контракт. Идеален ли он и стоит делать все исключительно в этом стиле — я уверен, что нет. Но, если у тебя, за твоими методами спрятан IPC, если предполагается отмена (а я считаю что токены отмены надо передавать всегда явно — то дефолтный инфинит — это антипаттерн — потом бесконечно утомительно искать где же именно оно бесконечно ждет) — то вот тебе готовый контракт/паттерн методов, который подходит много где.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Danchik, Вы писали:
D>>Вот хотелось бы знать что так возмущает. Если задача упирается в сеть или диск — async/await именно то что доктор прописал.
_>Ну вот простейшая классическая задача: скопировать файл (читаем его в буфер в памяти и параллельно записываем на диск в новое место). Эта задача собственно вот только в диск и упирается. И ты реально считаешь, что для её реализации будут эффективнее сопрограммы с асинхронным вводом-выводом? )))
Не будем вдаваться в крайности. То что требует дикой скорсти я запущу в одном потоке или распаралелю как надо без асинков.
[Skip]
_>Вот, здесь уже всё сказано корректно (ну разве что apache на потоках держал всё же побольше 2-3 пользователей). Только вот ты как-то забываешь, что основной сценарий из мира бэкенда, является вырожденным практически во всех остальных областях.
Не используй если не надо, хорошо что оно есть. У меня бакенды основное.
Здравствуйте, alex_public, Вы писали:
_>Ну вот простейшая классическая задача: скопировать файл (читаем его в буфер в памяти и параллельно записываем на диск в новое место). Эта задача собственно вот только в диск и упирается. И ты реально считаешь, что для её реализации будут эффективнее сопрограммы с асинхронным вводом-выводом? )))
Она не простейшая. В FAR был почивший? плагин делающий это хотя бы эффективно. Нужно один/два больших буфера (очень больших, типа 16Мб+) — в него асинхронно читаешь максимально большими блоками (буфер должен уметь в много файлов) — ну параллельно пишешь. Тебе не нужно 2 потока для чтнения/записи и их данных — ты можешь просто дирижировать из одного потока, тем самым не израсходовав ресурсы (стэк, прочие ресурсы на поток). Стратегии копирования с одним HDD — одни, а с несколькими — другие.
_>Или же просто запустить эту операцию в отдельном потоке. ))) Что будет намного проще и эффективнее.
Вернемся к тому, что нужен будет "арбитр" связующий задание и UI и трэкающий события. Вспоминаем классику MFC и радуемся беспорядочным посылкам непонятно чего. Ничего проще тут нет. Ну про преимущества пула vs на каждый чих создавать потоки можно долго спорить (я бы лично создавал чаще, чем держал 10 бесполезных потоков). Но сейчас то точно все тюнится. В чем проблема. Более того таскм есть LongRunning. Предпочитаешь Thread vs TPL — твое право. И то и то имеет место быть в практике.
_>Вот, здесь уже всё сказано корректно (ну разве что apache на потоках держал всё же побольше 2-3 пользователей). Только вот ты как-то забываешь, что основной сценарий из мира бэкенда, является вырожденным практически во всех остальных областях.
Корректно да есть нюанс. Если перенести всё на асинк запросы к БД — на нее потенциально изменится характер нагрзуки — и реальный выхлоп может изменится всхудшую сторону. БД предпочитают последовательное выполнение. Да и параллелизацию самих запросов mssql включает весьма неохотно, потому, что можно сильно огорчить если переоценить свои возможности. (Я в том смысле, что типичный веб сервер с 10 честными потоками в пуле это еще надо умудрится пригрузить, если он конечно не делает ахинеи). Поэтому тут солидарен с вами обоими.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Serginio1, Вы писали:
S>> То есть цифры тебя не переубеждают?
ЕМ>Я пока не понял, какое эти цифры имеют отношение к переключению контекста между потоками.
Не знаю. Но профит от async awaite существует. Назови от чего? S>>Я привел тебе примеры того, что асинхронный код увеличивает производительность на серверах с количеством запросов больше 100.
ЕМ>Насколько я понимаю, там речь идет о высокоуровневых API, которые сами по себе весьма толсты и неуклюжи, и где почти любая оптимизация способна дать ощутимый эффект.
Нет там там по сути все превращается в разницу между обычный Task.Delay (любые методы async ) против Thread.Sleep() (WaitOne).
Там и сравниваются
// GET api/<controller>
[HttpGet]
public async Task DoLongRunningOperationAsync()
{
await Task.Delay(2000);
}
public class LongOperationController : ApiController
{
// GET api/<controller>
[HttpGet]
publicvoid DoLongRunningOperation()
{
Thread.Sleep(2000);
}
}
Как я писал для запроса к базе расположенной на другом (других) компьютерах.
Это легко можно произвести.
S>>Ну и IoT это далеко не смартфоны. Это могут быть типа raspberry pi
ЕМ>У которой частота порядка гигагерца, и памяти минимум 256 Мб, а делается на ней в основном то же самое, для чего раньше хватало единиц мегагерц и десятков-сотен килобайт.
Ну когда то код был однопоточным и программа еле умещалась в 64кб на ДВК-2. Какие уж там 256 Мб. Тогда дискеты 5 дюймовые!
Просто в свое время вместо yield народ использовал файберы.
и солнце б утром не вставало, когда бы не было меня
AG>Ранее, ЕМНИП во времена Windows 3.11, понятие "асинхронность" не реализовывалось через multi-threading. AG>Тогда были специальные "асинхронные" реализации. Которые, ради совместимости, существуют и по сей день (но реально уже давно не используются). AG>Теперь (последние лет 20-ть): асинхронность реализуется через multi-threading.
Все с точностью до наоборот. Внутри винды весь ИО асинзронен, есть асинхронное АПИ — оно более "нативно", есть синхронное — оно внутри реализовано через асинхронное + ожидание его завершения.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, Mystic Artifact, Вы писали:
MA>Здравствуйте, AlexGin, Вы писали:
AG>>Мы можем сделать отдельный (рабочий) поток и в этом окне. И как-правило делаем его. MA> Не в обиду, но окно имеет весьма специфическую связь с потоком.
Поток (рабочий поток исполнения) — естественно напрямую с окном не связан
В OS с графическим интерфейсом пользователя — все окна — это GUI-шный интерфейсный поток.
Рабочий поток — это несколько иное. Это именно сущность для рассчётов или длительных операций.
MA>С точки разгребания сообщений — тут скорее поток владеет окном. ADD: Я в не обиду, имел ввиду, что вы с колесиком наперегонки начали перлы выдавать в подветке.
Где мои перлы!?
Допускаю, что не расписывал мысли очень подробно.
Из-за чего — допускаю некорректное понимание изложенного мною выше.
Но никаких перлов — вроде здесь не излагал.
MA>Я еле понял что ты имел ввиду. Глаз ухватился за первое предложение и не захотел понимать дальше.
AG>>Можно также и "прокачивать_сообщения" OS — чтобы не было "замораживания" элементов GUI MA>Безусловно. Более того в некотором смысле многие так и работают миксируя несколько очередей сообщений в одном цикле сообщений (нестандартном). Но практической сути это не меняет. Проблема только неоптимальности.
На сегодняшний день — правильнее применять многопоточность, нежели прокачку сообщений.
AG>P.S. Локального сохранения (в файл) это не касается, если файл не совсем гигантского размера, а вот для работы с далеким серваком — это будет в тему. MA> На самом деле это касается исключительно любого IO. Достаточно вставить в системник битый хард и часто можно будет наблюдать что некоторые приложения крайне жестко залипают, в то время как, тот же какой-нибудь злополучный хром — спокойно грузится как не бывало и браузит интернет, и его не волнует, что диск без буквы неожиданно притупил половину приложений. (Понятно, что как повезет, но думаю, идея понятна).
Есть принцып KISS.
Переусложнять архитектуру приложения, конечно можно, однако — не нужно.
Считать, что диск будет тупить, и из-за этого случая (вероятного на 0.1%) городить монстра —
всё-таки не следует.
А вот вариант, что твоё оптоволокно зацепил ковш экскаватора, учесть всё-же можно бы
(хотя и это — часто не учитывают и приложение ведет себя неадекватно при потере connect-а).
Здравствуйте, ononim, Вы писали:
AG>Теперь (последние лет 20-ть): асинхронность реализуется через multi-threading.
O>Все с точностью до наоборот. Внутри винды весь ИО асинзронен, есть асинхронное АПИ — оно более "нативно",
+100500
Об этом — я и сообщал выше.
O>есть синхронное — оно внутри реализовано через асинхронное + ожидание его завершения.
Мне не важно — как оно внутри OS реализовано.
Мне важно — как более рационально мне сделать одновременное выполнение разных функций в моём приложении.
На сегодняшний день — это рациональнее сделать — разделив алгоритм выполнения на несколько потоков
(если этот алгоритм позволяет это сделать).
Здравствуйте, AlexGin, Вы писали:
AG>Поток (рабочий поток исполнения) — естественно напрямую с окном не связан AG>В OS с графическим интерфейсом пользователя — все окна — это GUI-шный интерфейсный поток. AG>Рабочий поток — это несколько иное. Это именно сущность для рассчётов или длительных операций.
Ну вот опять. Почему рабочий поток это сущность, да еще с этим высоким предназначением? Это вполне физическое явление во вполне конкретных процессорах. И почему для рассчетов и длительных операций? Нет же — лучше всего они умеют исполнять ноп или и вовсе спать. Что за загрузка задач наперед через определения? Вы как-то не правильно используете потоки, заставляя их волочь какие-то вычислительные задачи. К ним нужно же, с любовью и пониманием. Схватил, вывел из системы и спать навеки до резета. Хорошо — энергию не кушают. Заняты *тоже* полезным делом — энергию экономят.
AG>Где мои перлы!?
Я вообще-то заранее извинился, подчеркнув, что это как бы и не важно, т.к. в итоге я расшифровал твой посыл. Но создать поток из окна — это безусловно пёрл. Я вот с телефона не могу на десктопе порождать потоки, а ты?
AG>На сегодняшний день — правильнее применять многопоточность, нежели прокачку сообщений.
Это мягко говоря не так. Всегда можно найти ситуационно лучшие решения в плане реализации, но потребители как раз и занимаются забором новых сообщений и как правило в цикле. Более того, задачи не требующие многопоточности, что? очевидно, что не нуждаются в ней. Это решение иногда на рантайме, чаще на программисте, но уж точно не на "на сегодняшний день повитуха задекларировала".
AG>Есть принцып KISS.
Это херня полная для хипстеров. Ни один реальный проект не целуется ни в куда. Лучшее что можно там ожидать — адекватную документацию, как это должно работать, но вообще высший класс — это увидеть документацию в духе как это реально работает (коей обладают единицы). В реальных проектах никакими KISS не пахнет, потому ,что ехать нужно сегодня, и лучше максимально быстро. И да-да, по ходу пьессы, экономя те самые неиспользуемые младшие 2-3 битов в адресах на объекты.
AG>А вот вариант, что твоё оптоволокно зацепил ковш экскаватора, учесть всё-же можно бы (хотя и это — часто не учитывают и приложение ведет себя неадекватно при потере connect-а).
Во-первых, у меня не оптоволокно, а витая пара. Во-вторых, она войну пережила. Поэтому, если не хватает фантазии своей — то тут я лучше воздержусь. Я считаю, если я парсю 1кб кода подымая при этом 100500 хидеров — это очень и очень асинхронная операция. Настолько асинхронная, что ей только не хватает выставить приоритет не только потребления CPU, но и I/O.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>При современном размашистом подходе к разработке софта, о накладных расходах на потоки имеет смысл начинать думать не раньше, чем количество потоков в приложении достигнет нескольких сотен.
Если эти потоки почти нихрена не делают, то да. Если же они постоянно занимаются вычислениями, то придется думать уже при 4-х потоках на ядро.
Здравствуйте, Kolesiki, Вы писали:
K>Речь о том, что async/await (которые как бы смахивают на асинхронность, но которые НЕ ЯВЛЯЮТСЯ параллельным исполнением) нафиг не нужны.
Именно параллельным исполнением они и являются, если ты специально шедулер не подменил так, чтобы он только одну задачу выполнял в параллель.
K>По кр. мере ты не показал НИ ОДНОГО случая, когда они необходимы.
Никто и не говорит, что они необходимы. Они просто удобны, ибо сильно упрощают код.
K>Практически все случаи абсолютно спокойно разруливаются трэдами или легковесными тасками.
async/await, внезапно, — это и есть синтаксический сахар над тасками.
Здравствуйте, Lexey, Вы писали:
L>Если эти потоки почти нихрена не делают, то да. Если же они постоянно занимаются вычислениями, то придется думать уже при 4-х потоках на ядро.
Я отстал от жизни. А кто сейчас может в 4 потока на ядро? И что это значит? Какие ресурсы ядра при этом разделяются?
Здравствуйте, Lexey, Вы писали:
L>Если эти потоки почти нихрена не делают, то да.
В контексте этого обсуждения большинство потоков бОльшую часть времени ни хрена не делает.
L>Если же они постоянно занимаются вычислениями, то придется думать уже при 4-х потоках на ядро.
Думать придется об общей нагрузке. О затратах на переключение контекста думать нет смысла — любые вычисления их многократно превосходят.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Думать придется об общей нагрузке. О затратах на переключение контекста думать нет смысла — любые вычисления их многократно превосходят.
Коллега remark как-то показывал, что переключение контекстов имеет значение
На момент сабмита моей реализации самая быстрая реализация была за Haskell'ем с результатом 4.59 секунд, следующая за ней — С++ с результатом 4.74 секунды. Так же можно отметить: самая быстрая реализация на Java – 7 сек.; Scala – 15 сек.; Erlang – 111 сек.; Ruby — 131 сек.; Python — 221 сек. Полную таблицу можно видеть здесь.
Результат моей реализации — 0.72 секунды.
Когда-то давно у Рихтера читал, что это до 2 тысяч тактов, а при переходе ещё по разным ядрам может быть и того хуже. Разве нет?
Здравствуйте, уважаемый Mystic Artifact, Вы писали:
MA>Ну вот опять. Почему рабочий поток это сущность, да еще с этим высоким предназначением?
Никто о "высоком_предназначании" не говорит. Просто — некоторая полезная необходимость.
MA>Это вполне физическое явление во вполне конкретных процессорах. И почему для рассчетов и длительных операций?
А где ещё делать длительные операции? Насчёт расчётов — пока забудем, но делать длительные операции в GUI-потоке: просто ужасно.
MA>Нет же — лучше всего они умеют исполнять ноп или и вовсе спать. Что за загрузка задач наперед через определения? Вы как-то не правильно используете потоки, заставляя их волочь какие-то вычислительные задачи. К ним нужно же, с любовью и пониманием. Схватил, вывел из системы и спать навеки до резета. Хорошо — энергию не кушают. Заняты *тоже* полезным делом — энергию экономят.
В этом случае, разработчик может гордо сказать:
— Наш сервис/приложение мнгопоточно!
Правда, что за необходимость в этой много-поточности разработчик объяснить НЕ может
MA>Но создать поток из окна — это безусловно пёрл. Я вот с телефона не могу на десктопе порождать потоки, а ты?
Поток к окну непосредственного отношения НЕ ИМЕЕТ.
Создаётся он — из нашего приложения (или сервиса).
При этом, сигнал на создание потока — может генерироваться из любого места нашего проекта.
Также возможен вариант — создание потока при старте и ожидание им запроса (например — в очереди запросов) на полезную работу.
AG>На сегодняшний день — правильнее применять многопоточность, нежели прокачку сообщений. MA>Это мягко говоря не так. Всегда можно найти ситуационно лучшие решения в плане реализации, но потребители как раз и занимаются забором новых сообщений и как правило в цикле.
Так как раз для того, чтобы не делать закат солнцапрокачку сообщений вручную, и создаём новый поток (или используем какой-либо уже созданный ждущий поток).
MA>Более того, задачи не требующие многопоточности, что? очевидно, что не нуждаются в ней.
Мы здесь обсуждаем задачи, требующие парралелизма. И реализацию этого парралелизма.
Как один из вариантов реализации парралелизма — многопоточность (ИМХО наиболее популярный на сегодня).
MA>Это решение иногда на рантайме, чаще на программисте, но уж точно не на "на сегодняшний день повитуха задекларировала".
AG>Есть принцып KISS. MA>Это херня полная для хипстеров. Ни один реальный проект не целуется ни в куда.
Я написал это только для примера, что связь может быть не надежной.
Несмотря на то, что у меня оптоволокно и 4G-радиоканал, стараюсь учитывать возможность отсутствия коннекта при проектировании приложений.
Здравствуйте, AlexGin, Вы писали:
AG>Поток к окну непосредственного отношения НЕ ИМЕЕТ.
Не знаю, как в других системах, а в винде — имеет, и как раз непосредственное. Когда поток создает окно, очередь сообщений окна привязывается к этому потоку, и только он может выгребать оттуда сообщения. Поэтому нет проблем создать поток со своим собственным окном, но для обработки сообщений уже существующего окна в отдельном потоке требуются песциальные телодвижения.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, AlexGin, Вы писали:
AG>>Поток к окну непосредственного отношения НЕ ИМЕЕТ.
ЕМ>Не знаю, как в других системах, а в винде — имеет, и как раз непосредственное. Когда поток создает окно, очередь сообщений окна привязывается к этому потоку, и только он может выгребать оттуда сообщения. Поэтому нет проблем создать поток со своим собственным окном, но для обработки сообщений уже существующего окна в отдельном потоке требуются песциальные телодвижения.
Это окно имеет отношение к потоку. И нужно делать обработку сообщений.
Это как может быть поток без окна, но не может быть окна без потока (Может быть корова без молока, но не может быть молоко без коровы!)
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, AlexGin, Вы писали:
AG>Считать, что диск будет тупить, и из-за этого случая (вероятного на 0.1%) городить монстра - AG>всё-таки не следует.
0.1% — это очень, очень много. Это каждый 1000-ый файл.
Здравствуйте, Евгений Музыченко, Вы писали:
AG>Поток к окну непосредственного отношения НЕ ИМЕЕТ. ЕМ>Не знаю, как в других системах, а в винде — имеет, и как раз непосредственное.
Там вообще-то речь идёт о рабочем потоке выполнения (не путать: с интерфейсным) — для которого очередь сообщений окна совершенно не актуальна.
ЕМ>Когда поток создает окно, очередь сообщений окна привязывается к этому потоку, и только он может выгребать оттуда сообщения.
Это — об GUI-шном (интерфейсном) потоке выполнения.
Обычно — такой поток в приложении единственный.
Впрочем, в случае необходимости, можно создать свой (и даже нескольо своих) интерфейсных потоков.
ЕМ>Поэтому нет проблем создать поток со своим собственным окном, но для обработки сообщений уже существующего окна в отдельном потоке требуются песциальные телодвижения.
Здравствуйте, AlexGin, Вы писали:
AG>Там вообще-то речь идёт о рабочем потоке выполнения (не путать: с интерфейсным) — для которого очередь сообщений окна совершенно не актуальна.
Я к тому, что при попытке распараллеливания "в лоб" могут возникать забавные эффекты.