Здравствуйте, Ikemefula, Вы писали:
V>>Вообще-то, да, с синтетикой. Если сравниваются голые затраты механизма диспетчеризации событий.
I>Это никому не интересно. Скажем, это не дает объяснения, почему веб-приложения массово пишутся на менеджед платформах, хотя казалось бы, они вечно испытывают нехватку ресусорв, памяти, процессора и тд и тд. I>Если смотреть синтетику, то веб-приложения должны писаться на С++. А вот десктоп приложения, где вагон ресурсов, почему то до сих пор частенько пишутся на С++, хотя я бы не сказал что в большинстве случаев. Казалось бы — должно быть наоборот. Ан нет. I>А если глянуть на реальные задачи, стновится понятно, где чего экономится. Скажем ручное управление памятью в веб-приложении задача адски сложная и неудивительно, что GC справляется гораздо лучше -> managed. Цена низкоуровневой оптимизации в таких задачах слишком высока, потому весь функционал предельно упрощен. А в десктопе все проще — ресурсов в пересчете на задачу больше + есть вещи, которые требуют перформанс. Вот здесь ручные оптимизации вводить достаточно легко и цена таких изменений сравнительно мала, отсюда ясно, что для десктопа все еще актуально писать на С++.
Думаю, и в десктопе полно приложух, где достаточно реакции управляемых сред. Дело не в этом, а в том, что исторически производительность серверных приложух меряется на клиенте через время отклика. Так вот, время отклика, получаемое из-за сети, позволяет чувствовать себя комфортно даже всякому тормозному коду на серваках. Но ситуация постепенно меняется, сетка убыстряется... Не зря же IIS отдает статические ресурсы не выходя из ядра...
I>Реалтайм приложения, что характерно, требуют в первую очередь корретной работы с ресурсами, низкоуровневый перформанс дело второстепенное. Отсюда понятно, почему приложения для биржи и тд, пишутся в т.ч. на Джаве той же.
Уже не пишутся. Джава уже умирает на биржах.
I>Есть другие случаи, скажем серверные приложения которые требуют достаточно высокий перформанс в задачах, которые упираются в низкоуровневый перформанс, такие невозможно решить в менеджед — обработка звука, видео, изображений.
Ну так и чего споришь, если сам знаешь? Да, звуковые пакеты на серверах диспатчат на нейтиве, там сотни тыщ событий в сек. На управляемых средах это в принципе невозможно. Причем, речь даже не об обработке, а о простом диспатчинге.
I>Менеджед применяется очень осторожно и всегда вместе с нативными библиотеками.
Управляемая часть там занимается "управлением" максимум. ))) Т.е. той логикой, которая происходит в момент установления/разрыва канала, т.е. тем, что занимает 0.00001% всех ресурсов.
I>>>Это все теория. А на практике один лишь переход в ядро и обратно даст столько такто, что покроет минимум десять таких проходв. V>>Не каждый ядерный вызов тяжел. Стоимость голой SYSENTER не так уж высока.
I>Давай ближе к конкретному примеру.
Например ф-ия АПИ GetSystemTimeAsFileTime. Погоняй на досуге.
V>>Ну гонок при описанном сценарии избегаем в любом случае. А голодание лечится завязкой шедуллинга на состояние прикладных данных. I>"Вот простой пример — три короутины, каждая готовит данные для одной из двух других, эдакое колечко. Нарушаешь порядок — получаешь проблемы."
Хочешь получить подробный ответ — спрашивай подробно.
I>>>А вот мне кажется, что проблемы уже могут быть в случае с тремя короутинами, каждая из которых готовит данные для другой.
V>>Простейшая автовыравнивание нагрузки — взаимная очередь фиксированного сверху размера, блокируемая для кода короутины, если очередь полна при записи или пуста при чтении. Но есть и еще более динамичные варианты, например, на основе некоей информации по обратной связи. Можно сэмулировать простейший фильтр 1-го порядка по обратной связи по информации о текущей длине очереди, по его показаниям фибер-производитель может назначать себе "штрафы".
I>Вот так время процессора начинает расходоваться непойми на что.
Один шаг фильтра 1-го порядка — это одно умножение и одно сложение. Вот и весь шедуллинг. ))
V>>У каждой короутины доложен быть некий сигнал готовности, чтобы она не получала управление для "холостого" оборота. В чем будет заключаться этот сигнал — сугубо прикладная хрень. I>То есть, гарантий никаких, что и требовалось доказать, все конфликты надо разруливать руками, руками и еще раз руками.
Коллега... Как бы тебе сказать помягче... Ну конечно, кол-во потоков, как аппаратных, так и легковесных, а так же способы их взаимодействия являются частью решения прикладной задачи.
Здравствуйте, vdimas, Вы писали:
I>>Есть другие случаи, скажем серверные приложения которые требуют достаточно высокий перформанс в задачах, которые упираются в низкоуровневый перформанс, такие невозможно решить в менеджед — обработка звука, видео, изображений.
V>Ну так и чего споришь, если сам знаешь? Да, звуковые пакеты на серверах диспатчат на нейтиве, там сотни тыщ событий в сек. На управляемых средах это в принципе невозможно. Причем, речь даже не об обработке, а о простом диспатчинге.
Показываю, что сравнение с синтетикой не дает ответа ни на один вопрос.
I>>Давай ближе к конкретному примеру.
V>Например ф-ия АПИ GetSystemTimeAsFileTime. Погоняй на досуге.
с IO completion на GetSystemTimeAsFileTime ? Ловкач
V>>>Ну гонок при описанном сценарии избегаем в любом случае. А голодание лечится завязкой шедуллинга на состояние прикладных данных. I>>"Вот простой пример — три короутины, каждая готовит данные для одной из двух других, эдакое колечко. Нарушаешь порядок — получаешь проблемы."
V>Хочешь получить подробный ответ — спрашивай подробно.
I>>>>А вот мне кажется, что проблемы уже могут быть в случае с тремя короутинами, каждая из которых готовит данные для другой.
V>>>Простейшая автовыравнивание нагрузки — взаимная очередь фиксированного сверху размера, блокируемая для кода короутины, если очередь полна при записи или пуста при чтении. Но есть и еще более динамичные варианты, например, на основе некоей информации по обратной связи. Можно сэмулировать простейший фильтр 1-го порядка по обратной связи по информации о текущей длине очереди, по его показаниям фибер-производитель может назначать себе "штрафы".
I>>Вот так время процессора начинает расходоваться непойми на что.
V>Один шаг фильтра 1-го порядка — это одно умножение и одно сложение. Вот и весь шедуллинг. ))
Да, я в курсе. Почему то в реальных приложениях используется какой нибудь round robin. Дураки наверное, не знаю что можно одно умножение и одно сложение сделать.
V>>>У каждой короутины доложен быть некий сигнал готовности, чтобы она не получала управление для "холостого" оборота. В чем будет заключаться этот сигнал — сугубо прикладная хрень. I>>То есть, гарантий никаких, что и требовалось доказать, все конфликты надо разруливать руками, руками и еще раз руками.
V>Коллега... Как бы тебе сказать помягче... Ну конечно, кол-во потоков, как аппаратных, так и легковесных, а так же способы их взаимодействия являются частью решения прикладной задачи.
Ты не отвлекайся, лучше покажи ту магию, кторая даст некие гарантии.
Здравствуйте, alex_public, Вы писали:
I>>Это никому не интересно. Скажем, это не дает объяснения, почему веб-приложения массово пишутся на менеджед платформах, хотя казалось бы, они вечно испытывают нехватку ресусорв, памяти, процессора и тд и тд.
_>Уже же обсуждали это. Подавляющее чисто всех серверов и баз данных написаны на C/C++ и именно там происходят все критические нагрузки. А то, что ты называешь гордым именем "веб-приложения" — это всего лишь тончайшая скриптовая прослойка между вызовами функций веб-сервера и базы данных. И не удивительно что там лидируют всякие php — у него запредельная скорость написания и модификации кода (говнокода обычно ). Причём для последнего даже не нужны никакие перекомпиляции т.п.
Эта тончайшая скриптовая прослойка составляет 99% логики тех задач за которые и платят деньги.
_>Вот если бы у нас сами сервера и базы данных были написаны на управляемых платформах, то твои слова уже имели бы реальное обоснование....
Сервера писаные на питоне или джаваскрипте считать или нет ?
Здравствуйте, alex_public, Вы писали:
_>>>Т.е. если завтра компилятор C# каким-то чудом ускорят раза в два, то ты скажешь "извините, но я возможно не буду этим пользоваться, т.к. я ещё не замерил есть ли у меня узкие места в моём ПО или нет"? ))) I>>Скорость компиляции является узким местом в средствах разработки. Полноценная навигация, интеллисенс, юнит тесты и прочие вкусности IDE невозможны без быстрого компилятора. Никто не будет пускать юнит-тесты, если проект надо компилировать по сорок минут.
_>Имелось ввиду ускорение генерируемого кода, а не скорости компиляции. Я конечно мутно сказал там... )
Переходить на новую версию просто ради перформанса, если мне это некритично, я точно не стану.
Здравствуйте, vdimas, Вы писали:
AVK>>Тогда поясни — либо "их" это все таки несколько более узкий круг, чем заявлено, либо я не принадлежу к "более опытным разработчикам".
V>Угу, характерно, что упоминание конкретного примера, где точный тип обязателен, ты проигнорил...
А ты умудрился проигнорить явно заданный вопрос, при этом ответить на сообщение, целиком состоящее из этого вопроса.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Здравствуйте, Ikemefula, Вы писали:
V>>Ты опять путаешь вызов ф-ии внутри короутины и передачу управления самой короутине. I>Не я, а ты. Ожидание возникает не от того, какие у тебя функции, а от того, когда нужно делать вызов и когда ожидать данных. Как ты чего вызываешь не имеет никакого значения. Если задача требует блокировки — надо делать ожидание. Если задача требует неблокирующий вызов — надо делать именно такой.
I>Покажи аналог для каждой из строчек I>
I>await X();
I>X();
I>
Ага, ясно, чего ты не понимаешь. У тебя код "линейный" в обоих случаях с т.з. потока управления, описанного программой. Разница там в том, в случае первой строчки будет крутиться "фибер" для внешней задачи (всех внешних задач по цепочке вложенности await), а во второй — нет. Для короутины это эквивалентно наличию/отсутствию каких-нить "yield next".
>>>С async все ясно — можно вызывать с ожиданием, можно без ожидания. А как быть с твоими мега-функциями ? V>>Должен быть сформирован сам фибер изначально, который будет запущен на исполнение. Код внутри него всегда с ожиданием, т.е. синхронный. I>Код покажи.
Тебе показывали формирование task через замыкания в современном С++. Т.е. единственно что удобнее в C# на мой взгляд — это более простой (синтаксически) захват контекста для короутины.
Для ассинхронщины обычно создается "зеркальное" АПИ, можно с суффикасами Async, как в дотнете. ))
Унутре таких АПИ обычно поведение такое: если задачу удается выполнить без блокировки, она выполняется сразу (и сразу вызывается callback с соотв. флагом), если нет, то инициализируется отложенная операция, т.е. создается короутина/замыкание (что в C#, что в C++), и добавляется "куда-то" в очередь. Это "куда-то", увы, сильно зависит от реализации. Это может быть либо системиная очередь, типа как alertable io (т.е. все описанное может происходить за один вызов АПИ ОС), либо некая пользовательская, со всякими адаптерами, если не получается привести все абстракции к хендлам ОС + привязанный к хендлу callback + user data. Пример такой ручной очереди тебе показывали уже. Но обычно все эти кишки прячутся в некий "системный фреймворк", который есть у каждой С++ конторы. )) Иногда их более одного.
Здравствуйте, vdimas, Вы писали:
I>>Покажи аналог для каждой из строчек I>>
I>>await X();
I>>X();
I>>
V>Ага, ясно, чего ты не понимаешь. У тебя код "линейный" в обоих случаях с т.з. потока управления, описанного программой. Разница там в том, в случае первой строчки будет крутиться "фибер" для внешней задачи (всех внешних задач по цепочке вложенности await), а во второй — нет. Для короутины это эквивалентно наличию/отсутствию каких-нить "yield next".
Покажи код, главное не забудь то о чем ты сам говорил:"В сигнатуре ниче не торчит. Нет ограничений на уровне контрактов."
V>Для ассинхронщины обычно создается "зеркальное" АПИ, можно с суффикасами Async, как в дотнете. ))
"В сигнатуре ниче не торчит. Нет ограничений на уровне контрактов."
Мне кажется или ты взял свои слова назад ?
V>Унутре таких АПИ обычно поведение такое: если задачу удается выполнить без блокировки, она выполняется сразу (и сразу вызывается callback с соотв. флагом), если нет, то инициализируется отложенная операция, т.е. создается короутина/замыкание (что в C#, что в C++), и добавляется "куда-то" в очередь.
"В сигнатуре ниче не торчит. Нет ограничений на уровне контрактов."
Здравствуйте, Ikemefula, Вы писали:
I>Эта тончайшая скриптовая прослойка составляет 99% логики тех задач за которые и платят деньги.
Причём тут логика, деньги и нагрузка? Ну что за детский сад?
Давай рассмотрим уже последовательность действий происходящих про работе какого-нибудь "веб-приложения". Возьмём что-нибудь самое самое распространённое по статистике. Ну например форум на php. И так:
1. На сервер приходит http запрос GET /viewforum.php?f=10
2. http-сервер (скорее всего Apache, по статистике) проделывает дохрена всякой работы (всякие виртуальные хосты, mod_rewrite, разрешения и т.п.) соотнося url и реальные данные на диске.
3. http-сервер видит что затребован скриптовой ресурс и переадресует запрос php демону, передавая ему имя скрипта, "?f=10" и ещё набор заботливо подготовленных данных.
4. И вот пошло исполнение нашего крутого управляемого кода, отвечающего за всю логику. Он берёт значение 10 (кстати, парсить самому не надо — это всё нативный код php уже подготовил) из строки запроса и подставляет его в нужное место строки sql запроса. После чего отсылает (через нативную функцию php) этот slq запрос в базу данных.
5. Сервер базы данных (скорее всего mysql, по статистике) исполняет запрос типа "найти последние 20 тем в разделе с id 10" делая кучу сложной работы включая не только сам поиск, но и например кэширование запроса. И возвращает результат в php в виде удобной таблички.
6. И вот снова пошёл крутой управляемый код. Он проходит в цикле по полученной табличке и указывает встроенному шаблонизатору в каких местах шаблона какие строки из таблички вставлять. Подчеркну, что собственно с самой страничкой (как со строкой) php код вообще не работает — он только указывает нативному коду php демона в каких местах идёт шаблон, а в каких данные из таблички.
7. php демон отрабатывает подстановку шаблона (нативный код php демона), формирует массив байт и передаёт его http-сервер.
8. http-сервер записывает данные в логи и отправляет поток байт клиенту по http.
О, кстати... А ещё Там по размеру кодов всё очень забавно видно. Значит у нас каждый запрос пользователя отрабатывают 3 монстроидальных нативных бинарника (apache, php, mysql) и сотня строк скрипта. Но естественно скрипт делает всю основную работу, ведь там же лоооогика....
Ну так что скажешь? ))) Хотя конечно все твои утверждения по прежнему остаются верны в какой-то степени... Действительно вся логика этого веб-приложения полностью реализована в управляемом (php) коде. И это совсем не исключение — действительно большая часть всего веба реализована (точно в таком же смысле как в примере выше) на управляемом коде (а именно на php). Но тебе самому то не смешно делать из этого какие-то выводы о производительности, потребление ресурсов и т.п.? )))
Вот напиши целиком такое же веб-приложение на php, не используя сторонний http-сервер и базу данных и ещё желательно не используя библиотеку php (которая целиком нативная). А потом сравни по быстродействию с классической реализацией... А после мы и поговорим насчёт "расхода ресурсов в управляемом коде". Только ведь ты же не идиот и не станешь такое писать, правильно? Тогда к чему прикидываться непонимающим насчёт реальных затрат ресурсов в веб'е?
Здравствуйте, Ikemefula, Вы писали:
V>>Один шаг фильтра 1-го порядка — это одно умножение и одно сложение. Вот и весь шедуллинг. )) I>Да, я в курсе. Почему то в реальных приложениях используется какой нибудь round robin. Дураки наверное, не знаю что можно одно умножение и одно сложение сделать.
Ты уже теряешь нить беседы. Ты говорил о ЗАВИСИМЫХ потоках, но упомянул алгоритм для независимых вычислений. Так вот, для баланса нагрузки в ЗАВИСИМЫХ системах хорошо подходят наработки ТАУ. Там вообще невозможно что-либо обеспечить без применения в шедуллинге знаний о мгновенной прикладной ситуации. Например, в виндах шедуллинг завязан на состояние окошек, если они есть у процесса, а в линухах — нет. ))) Поэтому, гуй на винды летал еще на 386-х машинах, когда любой другой гуй жутко тормозил.
V>>>>У каждой короутины доложен быть некий сигнал готовности, чтобы она не получала управление для "холостого" оборота. В чем будет заключаться этот сигнал — сугубо прикладная хрень. I>>>То есть, гарантий никаких, что и требовалось доказать, все конфликты надо разруливать руками, руками и еще раз руками.
V>>Коллега... Как бы тебе сказать помягче... Ну конечно, кол-во потоков, как аппаратных, так и легковесных, а так же способы их взаимодействия являются частью решения прикладной задачи.
I>Ты не отвлекайся, лучше покажи ту магию, кторая даст некие гарантии.
Грантии от ошибок? )) Нет такой магии ни в C# ни в С++, конечно. ))
посталенный процесс разработки и контроля кач-ва ПО дает результаты лучше любых языковых ср-в. но это темы для других топиков, которые мы уже не раз обсуждали.
Здравствуйте, vdimas, Вы писали:
V>Ты уже теряешь нить беседы. Ты говорил о ЗАВИСИМЫХ потоках, но упомянул алгоритм для независимых вычислений. Так вот, для баланса нагрузки в ЗАВИСИМЫХ системах хорошо подходят наработки ТАУ. Там вообще невозможно что-либо обеспечить без применения в шедуллинге знаний о мгновенной прикладной ситуации.
Правильно — нужны знания о ситуации. Кстати, у зависимых потоках появляются такие вещи как инверсия приоритетов. А у тебя все просто — одно сложение и одно умножение.
I>>Ты не отвлекайся, лучше покажи ту магию, кторая даст некие гарантии. V>Грантии от ошибок? )) Нет такой магии ни в C# ни в С++, конечно. ))
Гарантии чего тогда есть, что если все написано без ошибок, то все будет работаеть без ошибок ?
Здравствуйте, Ikemefula, Вы писали:
V>>Ты уже теряешь нить беседы. Ты говорил о ЗАВИСИМЫХ потоках, но упомянул алгоритм для независимых вычислений. Так вот, для баланса нагрузки в ЗАВИСИМЫХ системах хорошо подходят наработки ТАУ. Там вообще невозможно что-либо обеспечить без применения в шедуллинге знаний о мгновенной прикладной ситуации.
I>Правильно — нужны знания о ситуации. Кстати, у зависимых потоках появляются такие вещи как инверсия приоритетов. А у тебя все просто — одно сложение и одно умножение.
Да! Фильтр первого порядка оч неплох и обладает наилучшим переходным процессом. )))
А любая обработка данных по большей части — вычисление рядов и многочленов. Просто тут в ряду всего 2 члена.
Любое управление — оно же структурное. Т.е. суть не только в вычислениях, но в том, откуда берутся исходные данные и куда прикладывается результат. А насчет инверсии... Коллега, я же говорил про обратную связь. Нарисуй два потока и направление той связи, которая управляет приоритетом, там всё просто. Даже более чем. Все твои инверсии приоритетов — это способ решения конкуренции в сильно упрощенном варианте, в сравнении с полноценным ПИД из ТАУ. Т.е. это "затычка" на случай, когда низлежащщая ОС не понимает, что происходит на прикладном уровне. И просто ест ьтакой незатейливый способ в конце концов обслужить всех. Т.е. инверсии приоритетов нужны для недетерминированного переключения потоков, как в системах с выталкиванием, когда такое недетерминированное переключение создает конфликт. В случае кооперативной многозадачности приоритетами можно управлять точно, отказавшись от такого понятия-посредника м/у прикладной задачей и шедуллером как "приоритет", заменив её на живую, т.е. управляемую прикладным алгоритмом, очередь диспетчеризации задач.
V>>Грантии от ошибок? )) Нет такой магии ни в C# ни в С++, конечно. )) I>Гарантии чего тогда есть, что если все написано без ошибок, то все будет работаеть без ошибок ?
Хм)))
Вот эти строки с ошибками написаны или нет?
var x = calcX();
while(x >= 0)
doSmthng(x--);
А если после рефакотрингов calcX начнет возвращать uint?
Так же в асинхронщине в C#. Ты вполне можешь написать компиллируемый, но при этом некорректный код, использующий асинхронное АПИ. Собсно, новички в асинхронщине почти поголовно так и делают. Все компиллируется, но ничего не работает.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>То этот код будет работать с любыми потоками — что с синхронными, что с асинхронными, потому что код одинаковый для обоих случаев, так как можно yield спрятать внутри сокета. EP>На await-те так не получится — в асинхронной версии будет await(+async в объявлении) + по всему call stack'у выше, вплоть до вызова handler'а, точно также будут добавляться await+await.
На всякий случай спрошу: а ты уверен, что понимаешь как работает async\await?
private static async Task<int> F1()
{
return 42;//!!!
}
private static Task<int> F2()
{
return Task.FromResult(13);
}
private static async Task<string> FF()
{
Func<Task<int>> f = F1;//!!!var x = await f();//!!!var y = await F2();//!!!return (x + y).ToString();
}
private static void Main()
{
var r = FF().Result;//вызываем без await
Console.WriteLine(r);
Console.WriteLine("Done...");
Console.ReadKey();
}
"async" нужен для указания компилятору, что функцию нужно преобразовать в автомат и что в ее теле можно использовать await. Он не является частью сигнатуры и можно вызывать функцию как обычно и что-то делать с возвращаемым Task-ом.
На всякий случай: в примере выше вся работа ведется синхронно в том же потоке.
Здравствуйте, vdimas, Вы писали:
I>>Правильно — нужны знания о ситуации. Кстати, у зависимых потоках появляются такие вещи как инверсия приоритетов. А у тебя все просто — одно сложение и одно умножение.
V>Да! Фильтр первого порядка оч неплох и обладает наилучшим переходным процессом. ))) V>А любая обработка данных по большей части — вычисление рядов и многочленов. Просто тут в ряду всего 2 члена.
А зачем же тогда наработки из ТАУ если хватает одной простейшей эвристики ?
V>Т.е. инверсии приоритетов нужны для недетерминированного переключения потоков, как в системах с выталкиванием, когда такое недетерминированное переключение создает конфликт. В случае кооперативной многозадачности приоритетами можно управлять точно, отказавшись от такого понятия-посредника м/у прикладной задачей и шедуллером как "приоритет", заменив её на живую, т.е. управляемую прикладным алгоритмом, очередь диспетчеризации задач.
Твои идейки распространяются на случай из двух трех короутин, где все и так само работает. Общий случай такой — высокоприоритетный поток вдруг начинает ожидать результат низкоприоритетного потока, а тот спит, потому что выполняются другие потоки. Что бы такое не возникало, нужен хороший шедулер и возможность сообщать шедулеру, где какой приоритет и кто чего ожидает.
Кроме как расставить все руками у тебя ничего нет, правильно ?
V>>>Грантии от ошибок? )) Нет такой магии ни в C# ни в С++, конечно. )) I>>Гарантии чего тогда есть, что если все написано без ошибок, то все будет работаеть без ошибок ?
V>Хм))) V>Вот эти строки с ошибками написаны или нет?
От тебя было утверждение про некие гарантии. Хочу увидеть эти гарантии примером кода.
Здравствуйте, alex_public, Вы писали:
_>Давай рассмотрим уже последовательность действий происходящих про работе какого-нибудь "веб-приложения". Возьмём что-нибудь самое самое распространённое по статистике. Ну например форум на php. И так:
php не интересно. httpy, tornado, twisted годятся ? В стеке asp.net нативной фигни наверное только http.sys.
"await" использует текущий контекст синхронизации. В случае консольного приложения его нет, поэтому работа ведется на основе ThreadPool.
В WPF приложении, например, используется специальный контекст синхронизации, запускающий таски в UI потоке. Аналог второго примера там выдаст, что все делается в том же потоке.
Здравствуйте, Ikemefula, Вы писали:
I>php не интересно.
Ага, ага, язык на котором написана большая часть современного веб и неинтересен. Понятненько... )
I>httpy, tornado, twisted годятся ?
О, кстати эти товарищи мне очень хорошо знакомы. У нас то сейчас вся серверная часть на питончике живёт... Правда этих всё же лучше через nginx (в качестве прокси) раздавать, за одно и статику на него скинуть.
I>В стеке asp.net нативной фигни наверное только http.sys.
Ну да, ну да... Всего то только самый основной модуль и всё.
Здравствуйте, alex_public, Вы писали:
I>>php не интересно.
_>Ага, ага, язык на котором написана большая часть современного веб и неинтересен. Понятненько... )
Это сильно спорное утверждение.
I>>httpy, tornado, twisted годятся ?
_>О, кстати эти товарищи мне очень хорошо знакомы. У нас то сейчас вся серверная часть на питончике живёт... Правда этих всё же лучше через nginx (в качестве прокси) раздавать, за одно и статику на него скинуть.
I>>В стеке asp.net нативной фигни наверное только http.sys.
_>Ну да, ну да... Всего то только самый основной модуль и всё.
Все что он берет на себя, это протокол http и ничего больше.
_>О, кстати, а mssql тоже не нативный?
А noSql движки БД куда деть ? Они через один то на джаве, то на дотнете, то на каком эрланге написаны.
EP>>То этот код будет работать с любыми потоками — что с синхронными, что с асинхронными, потому что код одинаковый для обоих случаев, так как можно yield спрятать внутри сокета. EP>>На await-те так не получится — в асинхронной версии будет await(+async в объявлении) + по всему call stack'у выше, вплоть до вызова handler'а, точно также будут добавляться await+await. A>На всякий случай спрошу: а ты уверен, что понимаешь как работает async\await?
.
Да, асинхронный код можно легко сделать синхронным, но как тут уже не раз обсуждалось — getline тут стандартный, изначально ничего не знающий об асинхронности — std::istream тоже самый обычный. Код который вызывает void foo также может ничего не знать об асинхронности — он просто передаёт istream&.
Здравствуйте, artelk, Вы писали:
A>"await" использует текущий контекст синхронизации. В случае консольного приложения его нет, поэтому работа ведется на основе ThreadPool. A>В WPF приложении, например, используется специальный контекст синхронизации, запускающий таски в UI потоке. Аналог второго примера там выдаст, что все делается в том же потоке.
I>>>>При чем если минимально усложнить код, тебе придется заниматься ручно диспетчеризацией навроде "execute_on_ui_thread"
EP>>>Так у тебя тоже ручная диспетчеризация в виде await/task/async
I>>Я нигде не указываю в каком потоке чего выполнить, я всего то указываю ожидание результатов, по потокам раскидает компилятор, EP>По потокам у тебя раскидает библиотека/среда на основе глобального состояния.
I>>а ты это делаешь руками. EP>ничто не мешает также задавать это параметрами среды
EP>>>То этот код будет работать с любыми потоками — что с синхронными, что с асинхронными, потому что код одинаковый для обоих случаев, так как можно yield спрятать внутри сокета.
1. Покажи, как это будет выглядеть, если foo возвращает результат? Причем, чтобы было, что "код который вызывает foo может ничего не знать об асинхронности".
2. Покажи, как это будет выглядеть, если foo принимает не istream&, а, например, адрес или путь к файлу.
EP>>>На await-те так не получится — в асинхронной версии будет await(+async в объявлении) + по всему call stack'у выше, вплоть до вызова handler'а, точно также будут добавляться await+await.
Async не является частью сигнатуры — можешь вызвать как обычную функцию и что-то делать с возвращаемым Task-ом.
Но таки да, придется возвращать Task<TResult>, вместо TResult, чтобы можно было делать "TResult r = await foo();". А что, на C++ можно вернуть TResult и сделать асинхронщину?