Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, artelk, Вы писали:
A>>Когда не требуется большое число одновременных задач?
_>Например при организации фоновых процессов не серверных приложений.
Это я повторил, убрав лишнее "не".
A>>Без поддержки языка работать с продолжениями неудобно — будет лапша.
_>Что подразумевается под поддержкой языком? К пример в boost.thread продолжения давно есть и вполне себе нормально работают...
Что-нибудь, что позволяет выпрямить такой код:
F1(..., a=>{
...
F2(..., b=>{
...
F3(..., c=>{
//use a, b and c
});
});
});
А в идеале, чтоб, если захочется, еще можно было, например, завернуть все в try/catch:
try
{
var a = await F1(...);
var b = await F2(...);
var c = await F3(...);
//use a, b and c
}
catch(Exception ex)
{
//...
}
A>>Интересует не "полностью аналогичная реализация", а аналогичная возможность — чтоб лапши небыло, но с масштабируемостью из коробки.
_>Ээээ, какая ещё масштабируемость в данном разделе? С этим обращаться ко второй части того моего сообщения... )
Нуу.. если приложение серверное, то почему бы и нет? Ну ок, оставим только "чтоб лапши небыло".
A>>А чем с акторами проще?
_>Ну это собственно дело вкуса. Т.е. лично мне больше нравится такая архитектура, исключительно по эстетическим признакам. И естественно подобное нельзя пытаться кому-то навязывать. Однако могу просто показать упрощённый пример, демонстрирующий разницу в этих стилях. Весь код на C++.
_>Значит с сопрограммами мы можем написать так:
_>_>void OnClick() async_code
_>(
_> textbox+=await_async([]{return download("http://...");});//download - блокирующая функция, запускается в отдельном потоке
_>)
_>
_>А в стиле акторов будет что-то вроде:
_>_>void OnClick()
_>{
_> thread([]{PostData(download("http://..."));}).detach();
_>}
_>void OnData(string data)
_>{
_> textbox+=data;
_>}
_>
_>Оно конечно длиннее, но лично мне больше нравится по ряду причин.
Кто и как вызывает OnData? Что за ряд причин?
_>>2. Когда требуется не большое число одновременных задач.
A>>Когда требуется большое число одновременных задач?
_>В основном при реализации высоконагруженных серверов.
Это я повторил, убрав лишнее "не".
A>>Еще раз, меня в этой ветке интересует, чтоб масштабируемость по ядрам была и чтоб при этом код в лапшу не превращался. И да, я имею ввиду сервис, не UI.
_>Если критична производительность, то я пожалуй не стал бы увлекаться всяческими архитектурными изяществами (типа сопрограмм, причём как в сомнительной .net реализации, так и даже C++ реализации), а решил бы проблему в лоб стандартными средствами. Причём в C/C++ их выбор тоже не маленький с разным уровнем продуманности программного интерфейса. Если в C++ стиле, то это Boost.Asio, а если в C стиле, то это libevent, libev, libuv. Все они достаточно вылизанные и заточенные на производительность.
Блин, ты пойми, я не только такты считаю, я хочу, чтоб все ядра использовались и IO асинхронный был, но, при этом, код в спагетти не размотало.
Вот, например, сделаешь ты зеленые потоки в одном системном потоке — остальные ядра будут проставивать, даже когда работа есть, запросы новые идут.
_>>>а для просто реализации зелёных потоков поверх пула системных ничего дописывать и не надо — оно просто работает
A>>Покажи?
_>Так я же говорю, если без семафора, то Евгений уже показал что всё работает. Ну т.е. он не показал собственно организацию пула потоков (это отдельное реализуется или берётся готовое из того же boost'a), а продемонстрировал, что boost.coroutine вполне дружат с многопоточностью. Кстати, что самое интересное, boost.asio дружит с многопоточностью по точно такой же модели (http://www.boost.org/doc/libs/1_56_0/doc/html/boost_asio/overview/core/threads.html), так что все 3 компоненты (пул потоков, сопрограммы, асинхронный ввод/вывод) без всяких напрягов собираются в единую системку.
Asynchronous completion handlers will only be called from threads that are currently calling io_service::run()
Подозреваю, что тут лишний перескок из IOCP thread, не?
_>Но опять же надо понимать, что даже такая крайне эффективная реализации сопрограмм всё равно имеет определённые накладные расходы. Так что если уж производительность уж совсем критична, то лучше забыть про сопрограммы. И кстати не такой уж и страшный код без них выходит. )))
От boost.asio тоже придется отказаться?
A>>Имхо, акторы хороши, когда модель приложения в виде асинхронно общающихся объектов, посылающих друг другу сообщения, является естественной для решаемой задачи. Неясно, нафиг они нужны для вышеупомянутого сервиса и для UI с кнопкой, по которой что-то асинхронно выкачивается. Можешь объяснить?
_>Для сервиса я их и не предлагаю. Хотя скажем Theron может и не плохо справился бы (http://www.theron-library.com/index.php?t=page&p=performance) в смысле производительности, но не вижу особого смысла тащить его для таких целей.
_>А вот скажем на асинхронное скачивание по кнопке в UI акторы очень даже не плохо ложатся. Правда для такой задачи не нужна мощная библиотека типа Theron, а достаточно тривиальной реализации (см. пример выше).