Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, gandjustas, Вы писали:
G>>>> Сейчас спектр систем, где заработает код на C#, примерно такой же, как у java и у обоих гораздо шире, чем у C++. EP>>>C++ работает и на десктопах, и на планшетах, и на телефонах (разве что кроме первых версий windows phone), и на 8-битных контролерах, и даже <b><u>внутри javascript</u></b> G>>А в браузере на клиенте?
EP>Да, в браузере, на клиенте — открой ссылку выше.
Не взлетело...
Хотя внутри там JS увидел.
EP>Даже QT работает.
Canvas+javascript
Можно было и покрасивше нарисовать.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
G>>В выделенном коде у тебя порождается новый поток. Это бредовая асинхронность...
_>А ты никакую другую и не сделаешь, если у тебя по условию задачи входной поток данных блокирующий.
А какой тогда смысл в асинхронности вообще? Запусти в отдельном потоке и радуйся.
Без асинхронного IO бесполезная тема. А тебя единственный способ превращения синхронного в асинхронный — создание потока. Я и предлагаю не мучать жопу с корутинами, а сразу на потоках построить.
G>>Дальше можно не продолжать. _>Я правильно понимаю, что это означает слив? )
Слив чего? Где исходник?
Яж говорю — сделаю тот же алгоритм в 3 раза короче.
G>>твоем примеру бесконечно далеко до async\await. _>Что-то ты вообще куда-то не туда полез. Async\await в C# без проблем умеет работать и в рамках одного потока и с несколькими (await Task.Run()). Аналогично Boost.Coroutine без проблем умеет работать и в рамках одного потока (собственно только это в ней и есть) и с несколькими (с несколькими строками дополнения, типа моих выше). Так что ситуация абсолютно симметричная.
Но Async\await умеет и в рамках нескольких потоков работать и с async io, а Boost.Coroutine — увы
Так что несимметричная.
_>Я показал пример, использующий работу именно с несколькими потоками, т.к. она наиболее интересна на практике. Однако точно так же можно было бы придумать и вариант со сменой источника данных на внутреннее асинхронный, которому уже не понадобились бы потоки.
Она только тебе интересно, потому что другие случаи ты сделать не сможешь.
На практике как раз самое интересное — асинхронный IO и масштабирование.
Если у тебя IO должен быть синхронный (странно почему, Windows поддерживает IOCP с тех пор когда буста еще не было), то просто делаешь потоки. Но у тебя наступает вполне резонная жопа с масштабируемостью.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>На чём по-твоему написано ядро Linux?
Ядро линуха — это плохой пример. Ядро линуха содержит очень небольшое количество реально сложного кода, и огромное количество довольно простого кода, но при этом имеющего дело с такими низкоуровневыми вещами, как физическая память, регистры аппаратуры и бинарные структуры фиксорованного, и при этом довольно простого, формата, описывающие данные, ходящие по сети или между хостом и какой-нибудь железкой.
Чистый си очень неплохо подходит для решения подобных задач. Но подобных программ в индустрии пишется подавляющее меньшинство.
Здравствуйте, -n1l-, Вы писали:
N>А вот всякие гномы и кеды и остальные из мира опенсорса сделаны на инкрементированных сях.
В основном гном написан на чистом си. Читать его код, не матерясь, невозможно. Проблема там, впрочем, заключается не в языке, а в том, что разработчики — пионеры. Достаточно посмотреть, как они работают с д-басом, чтобы все про них стало ясно.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>Stackful coroutine мощнее — и это факт. А реальные примеры я уже показал I>>А ассемблер еще мощнее. И что с того ?
EP>Вот это: EP>
EP>2. С помощью корутин решаются такие задачи, которые не под силу C# await. И не надо разводить демагогию на тему "это не нужно/это редко встречается".
J>Пример Яху всем известен, правда? Пара маргиналов написали систему на маргинальном языке (лиспе) и свалили. Яху помучилась-помучилась и переписала все на мейнстримовом языке.
Пример яху как раз шикарен. Пара маргиналов на маргинальном языке внезапно! в ошмётки порвала многочисленных конкурентов на мэйнстримовых языках, за что и были были куплены яху. Тут бы уже задаться вопросом, а с чего бы им это удалось?! Но ты акцентируешь внимание на том что в яху не смогла ни самих маргиналов удержать, ни проект ими поднятый, выдаёшь это за некое преимущество мэйнстримовых языков
А мне кажется, то что менеджмент яху, в отличии от раннего гугла, не умел строить бизнес силами маргиналов, как раз и есть причина их быстрого слива по всем направлениям
Здравствуйте, alex_public, Вы писали:
I>>Наоборот. Когда исполнение уходит в другой поток, совершенно незачем придумывать для этго какие то особенные формы вызова функций, наводе thread( ля ля ля) I>>То есть, независимо от диспетчеризации, код выглядит одинаково. В С++ это не получится
_>Ага, только это у нас и так шло выполнение в фоновом потоке. Соответственно непонятно зачем вообще плодить новый поток. Разве что потому что системке так удобнее (у неё нет диспечеризации в старый не ui поток)...
Всё в один поток не всунешь. Нужен инструмент, который дает единообразный код независимо от диспетчеризации. Если винда не умеет чего то диспетчеризовать в какой то поток, это ничего не меняет. Пишешь диспетчер и все дела — сам код каким был, таким и остался.
Здравствуйте, Кодт, Вы писали:
К>У С++ есть два плюса: мультипарадигменность и поддержка наследия. Он и в будущее смотрит, и прошлое не забывает. К>Сколько стоит перенести гору уже существующего кода с C++ на D? А без тотального переписывания?
Индустрия, наконец, осознала ту мысль, что реальный коммерческий проект может быть написан на смеси языков. Это, как бы, решает проблему, что делать с бабушкиным наследством.
К>Кстати, не на тот язык звереешь. Фортран — вот где ад.
Современный фортран — это очень хороший язык, для своей целевой ниши. Товарищи ученые способны писать на нем програмки, решающие их задачи. Просто не надо относиться к этому языку, как к языку общего назначения (и не надо путать Фортран с Фортраном IV).
был пример gevent, где этого не было. Это по твоему какой-то редкий случай? I>>Да, это редкий случай. Патчить можно и в джаве, и в дотнете, при чем без особых затруднений.
EP>Как ты пропатчишь что-нибудь типа std::getline?
Его не надо патчить, всё остаётся как было. Все что нужно — подсунуть ему стрим, который унутре будет yield вызывать. Вот yield и делается через патч.
Вот такие фокусы и в джаве, и в дотнете, и в питоне. Толко вот странно, мало кто этим занимается.
Более того — файберы в линуксе или винде использует примерно такое же количество людей, если не меньше.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
G>>Наверное потому что async\await отлично работает как на клиенте, так и на сервере. А ты сделал менее эффективный пример, который и этом нифига не масштабируется.
_>Клиент или сервер — это не принципиально. Важно количество соединений. И если мы имеем дело с системой под большие нагрузки (множество соединений), то уж точно глупо брать async\await из C# — это мягко говоря не лучший вариант по производительности.
Ты понять показываешь незнание предмета. Какой вариант по твоему лучший?
_>Место async\await из C# как раз в фоновой обработке нажатий на кнопки и т.п. Причём желательно в варианте с запуском потоков.
Пешы исчо....
G>>Если ты начнешь масштабировать свой подход, то он начнет дико тормозить. А если подход нельзя масштабировать, то нафига он такой нужен?
_>Какое масштабировать подход? У нас кнопка на экране для пользователя. По её нажатию в фоне запускается некий процесс, результат которого потом выдаёт на экран. Какое нафиг масштабирование тут? )))
Тут не надо. Тут достаточно потока.
Но видимо тупо везде создавать потоки неэффективно, поэтому и придумали IOCP, пулы потоков, таски и async\await.
_>И кстати как раз для таких вещей системные потоки вполне оптимальны. Более того, как раз если мы попробуем реализовать это без системный потоков, а наш фоновый процесс будер производит какие-то реальные вычисления, то у нас именно из-за отсутствия потоков начнёт подтормаживать интерфейс...
Это зависит от того что за фоновый процесс. Если там IO, то создание потоков — совсем не оптимальный способ. А практика показывает что подобные фоновые процессы в 99% случаев — io.
G>>Решить частную задачу по созданию асинхронности одной функции можно запустив её в отдельном потоке, дописав маршалинг вызовов в UI и получится меньше чем пляски с корутинами\шаблонами\макросами.
_>Ну собственно лично я действительно не вижу особых преимуществ от подобной линеаризации кода, что в .net, что в C++. Но если кому-то нравится, то почему бы и нет. И как мы видим C++ вариант при этом получается мощнее.
Пока не работает с async io говорить не о чем.
_>А так, конечно реальная потребность подобных вещей появляется только при реализации чего-то типа легковесных потоков. Но тут как раз .net вариант заметно слабее, т.к. уже становятся принципиальны накладные расходы.
Ты о чем вообще? Для чего тебе леговесные потоки?
задачку. Ты же обещался: "я напишу такой же на C# в 3 раза короче". Или уже всё, слив? ) G>>Дык я тебе уже написал, примерно с тем же уровнем детализации. _>Это где? Я не видел от тебя ни одного куска кода.
Ок, давай конкретнее, если сам мозгом не работаешь:
Было
void Echo(Stream s)
{
var buf = new byte[256];
while(true)
{
var len = s.Read(buf,0,buf.Lenght);
s.Write(bof,0,len);
}
}
Стало (жирным выделил что изменилось)
async void Echo(Stream s)
{
var buf = new byte[256];
while(true)
{
var len = await s.ReadAsync(buf,0,buf.Lenght);
await s.WriteAsync(bof,0,len);
}
}
А еще парой ловких движений можно и отмену прикрутить.
Но это ты можешь и в документации почитать.
G>>Еще раз повторю — все изменения только в дописывании async\await. _>Дописывание куда? По условиям задачи мы должны использовать существующий библиотечный код. Т.е. его нельзя модифицировать или переписывать.
Кому должны? Какой библиотечный код? Ты же пишешь реализацию оператора >> зная как он используется внтури функции. Это значит что исходники у тебя есть.
Для "черного ящика" ты так не напишешь. Да и в общем случае сделать из синхронного черного ящика асинхронный нельзя, потому что нет гарантии не нарушения инвариантов.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
G>>Думаю стоит глянуть на Mono и Xamarin, перед тем как толкать такие утверждения. Сейчас спектр систем, где заработает код на C#, примерно такой же, как у java и у обоих гораздо шире, чем у C++.
_>С учётом того, на чём написаны сами .net, mono, java, эта фраза звучит особенно пикантно. Видимо здесь присутствует какая-то магия. )))
Это тебе помогает писать код? Какая разница на чем рантайм написан, если ты прикладные вещи пишешь?
Почему-то факт, что райнтайм .NET написан на C++, не помогает произвольному скомпилированному коду на C++ одинаково хорошо работать на iOS, Android и в браузере на клиенте.
Тут же не вопрос яйца или курицы, а вопрос в том сколько надо кода написать, чтобы добиться результата. Увы по этому параметру C++ проигрывает, а в некоторых случаях в принципе не может быть использован.
Здравствуйте, gandjustas, Вы писали:
G>А какой тогда смысл в асинхронности вообще? Запусти в отдельном потоке и радуйся.
Да, это как раз самое лучшее решение (для работы с блокирующим кодом). Но оно далеко не всегда возможно. Проблема в том (на нашем примере), что ComplexFunction нельзя выполнять в отдельном потоке, а можно только в ui.
G>Без асинхронного IO бесполезная тема. А тебя единственный способ превращения синхронного в асинхронный — создание потока. Я и предлагаю не мучать жопу с корутинами, а сразу на потоках построить.
Да, можно. Опять же переписав сложную библиотечную функцию...
G>Слив чего? Где исходник? G>Яж говорю — сделаю тот же алгоритм в 3 раза короче.
, а от тебя пока не было ни одной строчки, а только отмазки. Приведи подобные выкладки (те же самые 4 пункта) на C#, а без этого ты сам понимаешь кем выглядишь...
G>Но Async\await умеет и в рамках нескольких потоков работать и с async io, а Boost.Coroutine — увы G>Так что несимметричная.
Как раз Boost.Coroutine только в рамках одного потока и работает. Это я её раскидал на несколько с помощью своего кода.
G> G>Она только тебе интересно, потому что другие случаи ты сделать не сможешь.
#define AsyncInputStream() __AsyncInputStream(__yield, __coro)
class __AsyncInputStream: public InputStream{
__Coro::caller_type& __yield;
__Coro* __coro;
public:
__AsyncInputStream(__Coro::caller_type& y, __Coro* c): __yield(y), __coro(c){}
InputStream& operator>>(vector<int>& buf) override
{
StartAsyncRead(buf, []{CallFromUI(__coro);});
__yield();
}
};
Соответственно StartAsyncRead — это функция из асинхронного IO API (типа libevent), которая вызывает callback (второй параметр) из ui потока после завершения работы. Ну вот тебе полноценный вариант без единого дополнительного потока. Давай, повторяй на C# в 3 раза короче. Хотя меня удивит если вообще сможешь хоть как-то повторить.
G>На практике как раз самое интересное — асинхронный IO и масштабирование. G>Если у тебя IO должен быть синхронный (странно почему, Windows поддерживает IOCP с тех пор когда буста еще не было), то просто делаешь потоки. Но у тебя наступает вполне резонная жопа с масштабируемостью.
Ещё раз, описываемые тобой проблемы с многопоточным вариантом актуальны только для специфической области типа написания высоконагруженных серверов. И если уж мы говорим о ней и нам критично быстродействие, то C# await/async тоже не стоит применять.
Здравствуйте, gandjustas, Вы писали:
EP>>std::getline тут стандартная, не модифицированная. Точно также можно протащить yield и через любую другую функцию G>Да, вот только надо очень хорошо понимать как работает эта функция. К счастью для переписывания синхронного кода в асинхронный в .NET не надо разбираться как он внтури устроен. Можно просто базвоые методы, которые делают IO сделать async, а дальше следуя руганиям компилятора добавить async\await во все методы выше по цепочке вызовов.
В цепочке вызовов находится код исходников которого нет, что теперь?
EP>>>>Что значит особый случай? Точно также можно завернуть tcp_stream. G>>>Надо очень хорошо знать как код работает внутри, чтобы делать такую асинхронность. EP>>Есть любая асинхронная функция которая принимает continuation/.then — мы ей передаём в этот continuation код с yield-ом внутри, что механически превращает остаток нашей функции в продолжение. G>Пример давай.
G>>>А как комбинировать такие асинхронные вызовы не то что не очевидно, а вообще непонятно как. EP>>Ты о чём? G>Напрмиер так: G>у тебя есть асинхронные функции f1 и f2, внтури они делают какой-то IO. Тебе нужно написать функцию f3, которая вызывает f1 и f2 параллельно, ждет их завершения и вызывает асинхронную операцию. G>Реальное применение такой функции — сервис поиска авиабилетов. Он обращается параллельно к десяткам перевозчиков, получает данные, выбирает лучшие варианты, отдает клиентам. Естественно это hiload сервис, который не может позволить себе создавать потоки.
int bar(int i)
{
// await is not limited by "one level" as in C#auto result = await async([i]{ return reschedule(), i*100; });
return result + i*10;
}
int foo(int i)
{
cout << i << ":\tbegin" << endl;
// instead of async can be any future with .then
cout << await async([i]{ return reschedule(), i*10; }) << ":\tbody" << endl;
cout << bar(i) << ":\tend" << endl;
return i*1000;
}
void async_user_handler()
{
vector<future<int>> fs;
// instead of `async` at function signature, `asynchronous` should be
// used at the call place:for(auto i=0; i!=5; ++i)
fs.push_back( asynchronous([i]{ return foo(i+1); }) );
for(auto &&f : fs)
cout << await f << ":\tafter end" << endl;
}
EP>>>>При этом код использующий этот поток не поменяется, а в случае с C# await — нужно будет патчить весь call-stack G>>>А зачем это делать? Преобразование синхронного кода в асинхронный — механическая операция, легко автоматизируется при желании. Я даже для стримов на roslyn такое переписывание делал. EP>>С такими же рассуждениями можно прийти к мысли что и yield, и await/async не нужны G>Практика то показывает что нужны. Причем тут рассуждения?
Ну ты говоришь что преобразование синхронного кода в асинхронный это механическая операция. Так и преобразование кода с await/yield — точно такая же механическая операция
G>То что ты считаешь что нужно патчить call-stack — вывод, основанный на неверной посылке.
(это при том что я сам практически не работаю ни с каким io). G>Без асинхронного IO это все смысла не имеет. Покажи пример с асинхронным IO.
Слушай, ну если ты не нацелен на конструктив, давай прекратим, ок? По второй ссылке Boost.Asio — самое что ни на есть асинхронное I/O, с тем самым IOCP под капотом
G>Основная проблема в том, что IOCP и другие механизмы не сохраняют стек, поэтому придется значительно извратиться чтобы на это натянуть stackfull coroutines.
Ты о чём? Корутина вместе со всем стэком ныряет в продолжение, для этого никакого специального "сохранения стэка" от асинхронного API не требуется
G>>>Для начала тебе надо будет async io реализовать на IOCP. EP>>Ты мне предлагаешь реализовать свои обвёртки поверх голого IOCP? Зачем? G>Без асинхронного IO все что ты пишешь не имеет смысла. Вообще.
Подожди, то есть ты думаешь что для C++ нет библиотек асинхронным API
G>Ты вообще представляешь как медленно будет работать твой пример с getline на реальном файле? G>Опубликуешь результаты забегов? При этом масштабирования такой подход не добавил. Ты не сможешь также запустить 100500 чтений файлов и выйграть хоть что-то.
getline может читать из любого стрима, например из сокета. В одном потоке будут крутится тысячи потоков с getline внутри, который ничего не знает об корутинах.
EP>>О том, что для того чтобы сделать yield с самого низа callstack'а на самый вверх, тебе придётся дублировать и модифицировать каждый уровень. Причём эти уровни могут находится в библиотеках к которым нет доступа. G>В смысле "нет доступа" ? G>Если библиотеки — "черный ящик", то и твой подход не поможет, потому что требует знать как внутри работа устроена. G>Если у тебя таки есть доступ к исходникам, то кто мешает сделать ctrl+c-ctrl+v и добавить async\await?
Детский сад — для того чтобы пользоваться библиотекой знать её код не обязательно. В нормальных библиотеках есть чётко определённый интерфес
EP>>У тебя нет кода std::getline (или аналога) — куда ты там собрался дописывать await? G>Если тебя нет когда getline, то как ты написал свой код? Он же полностью базируется на знании устройства getline, значит код у тебя есть.
Здравствуйте, gandjustas, Вы писали:
G>>>>> Сейчас спектр систем, где заработает код на C#, примерно такой же, как у java и у обоих гораздо шире, чем у C++. EP>>>>C++ работает и на десктопах, и на планшетах, и на телефонах (разве что кроме первых версий windows phone), и на 8-битных контролерах, и даже <b><u>внутри javascript</u></b> G>>>А в браузере на клиенте? EP>>Да, в браузере, на клиенте — открой ссылку выше. G>Не взлетело...
Можешь тут потыкать — там много примеров.
EP>>Даже QT работает. G>Canvas+javascript G>Ты о чем вообще?
Здравствуйте, Pzz, Вы писали:
M>>>[...] А время идёт и ждать, пока каждый говнопроект не сдохнет в шаблонно-указательных муках, нет никакого желания. Теперь вы осознаёте, что такое "невинное" существование С++ всё равно гадит в отрасль, не давая ей развиваться с другими, более достойными языками? Даже пример дам — Линукс. Я подобную халтуру не поставлю даже в бортовую радиолу, EP>>На чём по-твоему написано ядро Linux? Pzz>Ядро линуха — это плохой пример.
Плохой пример чего? Ты о чём? matumba считал что Linux это C++
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, gandjustas, Вы писали:
Pzz>>>C# работает только на венде, а все практические реализации Явы обладают красотой и грациозностью бегемота, пасущегося на лугах Страны Неограниченных Ресурсов. G>>Думаю стоит глянуть на Mono и Xamarin, перед тем как толкать такие утверждения. Сейчас спектр систем, где заработает код на C#, примерно такой же, как у java и у обоих гораздо шире, чем у C++.
Pzz>Моно — это пионерская поделка, годящаясь только на то, чтобы изготавливать пионерские поделки. Существенной проблемой при этом является то, что пионеры не в состоянии понять, что кроссплатформенные пионерские поделки надо тестировать на всех платформах, а не только на любимом компьютере разработчила. Поэтому даже для изготовления кроссплатформенных пионерских поделок моно не годится. А пионерские поделки под венду проще все же делать, используя родные для венды средства.
А что мешает протестировать моно на разных компьютерах?
Кстати я собирал в студии проект который взлете на mono. Я наверное что-то не так сделал.
Pzz>В этой связи приходится признать, что единственное применение моно заключается в том, что пионеры могут с умным видом заявлять в форумах, что C# подходит для кроссплатформенной разработки.
Расскажи это тут: http://unity3d.com/
Pzz>>>Кросплатформенный язык общего назначения типа "си с классами", не страдающий при этом врожденной склонностью к онкологическим заболеваниям, безусловно, нужен. G>>Практика показывает что эту нишу занял javascript.
Pzz>Яваскрипт занял нишу "хотим писать скрипты-плагины, но не на питоне". Кроме того, в силу политических, а не технических причин, явяскрипт имеет весьма специфические отношения с некоторыми платформами, такими, как веб-программирование (в основном на стороне клиента), и т.п.
Ну да, все происки ZOG.
Здравствуйте, Ikemefula, Вы писали:
EP>>>>Stackful coroutine мощнее — и это факт. А реальные примеры я уже показал I>>>А ассемблер еще мощнее. И что с того ? EP>>Вот это: EP>>
EP>>2. С помощью корутин решаются такие задачи, которые не под силу C# await. И не надо разводить демагогию на тему "это не нужно/это редко встречается".
EP>>Я писал не тебе. I>Это не важно. Ты на вопрос ответь.
На какой? На этот:
I>>>А ассемблер еще мощнее. И что с того ?
?
Ещё раз. Я озвучил факт, который оппонент не знал/не понимал. Что с этого? Ну как минимум теперь он знает
Вот ты тоже не знал, не верил, отрицал. Зато теперь "И что с того ?" — большой прогресс
Здравствуйте, Ikemefula, Вы писали:
I>Всё в один поток не всунешь. Нужен инструмент, который дает единообразный код независимо от диспетчеризации. Если винда не умеет чего то диспетчеризовать в какой то поток, это ничего не меняет. Пишешь диспетчер и все дела — сам код каким был, таким и остался.
Причём тут в один поток? Здесь речь не о запуске нового потока, а об исполнение продолжения в новом. Хотя инициации запуска была уже не в ui потоке (который мы там как-то ещё уже запустили). Смысла у этого особо не видно.
был пример gevent, где этого не было. Это по твоему какой-то редкий случай? I>>>Да, это редкий случай. Патчить можно и в джаве, и в дотнете, при чем без особых затруднений. EP>>Как ты пропатчишь что-нибудь типа std::getline? I> Его не надо патчить, всё остаётся как было. Все что нужно — подсунуть ему стрим, который унутре будет yield вызывать. Вот yield и делается через патч. I>То есть, I>