Предлагаю читателям обсудить в комментариях к этому сообщению следующую тему: стоит ли использовать Boost.Asio на стороне клиента. С серверами все понятно - там вменяемой альтернативы (на C++) нет. А вот с клиентами как?
Для "затравки" мое мнение: то, что клиенты до сих пор не используют асинхронный ввод/вывод - "дело времени" и связано с привычкой и ленью.
Да, можно выделить весь синхронный ввод-вывод в отдельный поток (thread). Но (!) как Вы собираетесь передавать данные в этот поток и получать данные из него? Конечно же через очереди. Ага, получаем как раз тот вариант (io_service + io_service::strand), что описан в проекте nmea_client. Т.е. без Asio это будет просто очередной "велосипед".
Я могу ошибаться. Мне очень интересны (контр)аргументы противоположной стороны. Буду рад их услышать и сделать какие-то выводы для себя.
19 комментариев:
Марат, здравствуйте.
Мне, к примеру, нечего кроме как asio использовать и там, и там. Как Вы правильно заметили: там вменяемой альтернативы (на C++) нет. Но а на клиенте что использовать если не asio? У меня нет проектов которые бы не использовали boost. Посему, нет смысла тащить в проект что-то еще.
Есть конечно коллеги, которые пишут с использованием Qt. Но им(по их словам), использовать asio несподручно, ибо что-то еще учить нужно. Другие прямо говорят: ну не понимаю я что там и как... как-то все сложно и мудрено... и т.д.
Я не представляю что еще использовать %)
Не BSD-сокеты или win-сокеты+IOCP же...
asio, ИМХО.
На днях мне привели доводы как раз против Boost.Asio (по крайней мере, асинхронной его части) в client-side. И надо же... я что-то растерялся. Ну не умею я рисовать код в воздухе и объяснять на пальцах.
Может быть, удастся продолжить дискуссию здесь. Вполне возможно, что я слишком "повернут" в сторону Asio и не замечаю чего-то.
Есть конечно коллеги, которые пишут с использованием Qt. Но им(по их словам), использовать asio несподручно
Это было одним из аргументов. Кстати, как соединять Qt и Boost.Asio я уже написал - ничего там сложного нет.
Еще были доводы: сложность и "code bloat", связанный с Asio. Но это слишком спорно, чтобы повернуть меня в другую сторону.
Еще были доводы: сложность и "code bloat", связанный с Asio
Ну а скажите(если вдруг замечали), какого уровня программисты в основном встречаются на Qt форумах? ;)
Все верно - те, кто учил программирование по документации Qt. Но откуда им знать что такое байндер и функциональный объект? Для большинства, слово "шаблон" отбивает всякое желание лезть туда.
Нет, это не стеб. Говорю о сформировавшемся впечатлении.
Ну а скажите(если вдруг замечали), какого уровня программисты в основном встречаются на Qt форумах
Мои, кхм, "оппоненты" (понравились, что скрывать) рассуждали весьма разумно. И Boost.Asio они используют, но только в server-side (это вообще их специализация). Просто досадно, что такой простой ответ, который уже давно готовил (nmea_client), вылетел из головы.
Другой пример.
Я всегда разделяю приложение на GUI и реализацию потому, что в моем понимании, реализация, обязана работать без "обложки". А Qt - это такой монстр, который не впихнешь куда угодно. И "отвязаться" от него не получится. Именно по этой причине я не использую Qt в реализации. Только STL+boost.
Я всегда разделяю приложение на GUI и реализацию потому, что в моем понимании, реализация, обязана работать без "обложки". А Qt - это такой монстр, который не впихнешь куда угодно.
Вот-вот - таких комментариев мне и надо. Спасибо.
Я всегда разделяю приложение на GUI и реализацию потому, что в моем понимании, реализация, обязана работать без "обложки". А Qt - это такой монстр, который не впихнешь куда угодно.
Да, согласен. Но если проект был сразу направлен на кроссплатформенность с GUI(Qt), то глубокое разделение интерфейса от реализации выльется в оверкод.
Если отвязаться от GUI(Qt), то для асинхронного вывода (о чем и стоял вопрос в первую очередь) бесспорно (для меня) asio на первом месте.
Если отвязаться от GUI(Qt)
В том то и дело, что я бы не стал рисковать (в т.ч. и будущим code reuse - а он точно будет) и завязываться на Qt - Вы посмотрите, что они делают с QtSvg в Qt5 (какая была жаркая дискуссия, пока ее не закрыли насильно). Не к месту будет сказано, но я был бы только рад, если подразделение Qt Software перешло в Intel.
WxWidgets? Они, насколько я помню, одно время и сами смотрели в сторону Asio.
выльется в оверкод
Сомнительно. Уж больно это понятие относительное. Написал бы кто ввод/вывод на Qt в отдельном потоке, чтобы сравнить (?). Например, переписал бы nmea_client.
Т.е. "оверкод" конечно будет. Но я предполагаю, что он будет в приемлемых рамках, которые с лихвой покрываются всеми плюсами подхода с разделением GUI (Qt) + network logic (Boost, Boost.Asio).
Вам не кажется, что код на boost::asio получается очень переусложнённым? (понимаю, что постепенно его писать легко - но как потом читать?) Например тот же пример nmea-client - его же нужно хорошо поковырять, чтобы собрать общую картину что там происходит и какая логика там заложена. А это очень плохо для больших проектов - там код либо читается сразу - либо является тревожным звоночком. Я уже видел несколько таких проектов, погибших под тяжестью кода. А сложность nmea-client, чтобы показать лишь чтение из порта - уже говорит не в пользу этой библиотеки.
Вам не кажется, что код на boost::asio получается очень переусложнённым?
Очень даже кажется.
Например тот же пример nmea-client
Это несколько притянутый пример, являющейся скорее базой для чего-то большего (к слову, из него вырезан парсинг NMEA-сообщений).
А это очень плохо для больших проектов - там код либо читается сразу - либо является тревожным звоночком.
Полностью с Вами согласен. Вот несколько причин сложности nmea-client:
1) Общая "многословность", обусловленная желанием написать код, читаемый как текст (и нежеланием долго думать над названиями).
2) Обобщенность - произвольные функторы вместо тех же boost::function или boost::future/boost::promise.
3) Форсированное использование (и поддержка) Asio custom memory allocation.
4) Дополнительная поддержка move semantic (мне и самому не нравятся "навесы" из #if-#endif).
5) task-based параллелизм (активный объект не владеет выделенным потоком, а использует существующий пул).
Пункты 1-4 вполне решабельны. Особенно в свете недавно принятого стандарта - многое из пространства имен boost переместится в std, да и лямбды могуть помочь с "липосакцией".
А вот пункт 5 вызывает сомнения - нужен ли task-based параллелизм в client-side (где проходит грань целесообразности?). В общем случае task-based параллелизм сложнее варианта "каждому страждующему по отдельному потоку".
Помнится, Джон Кармак на GDC говорил, что они отказались от task-based варианта в пользу потоков в виду высоких накладных расходов и неэффективности (могу ошибаться - чуть позже поищу этот текст и дам здесь ссылку).
С другой стороны, Intel активно продвигает именно task-based "движки" (см. ISN Blogs) и инструментарии (TBB).
Мое мнение таково: task-based параллелизм пока довольно сложен и не дает достаточно преимуществ, чтобы быть однозначным лидером. Но только пока. Предполагаю, что с ростом кол-ва ядер и развитием инструментариев будет наблюдаться переход большей части прикладного параллелизма на task-based.
Вам не кажется, что код на boost::asio получается очень переусложнённым?
Перечитал Ваш комментарий и увидел его под другим углом.
Asio samples - это лишь "весьма замороченный" вариант использования Asio. Один из множества вариантов (см. документацию Boost.Asio).
Сама библиотека (не framework!) наоборот максимально упрощает программирование асинхронного ввода-вывода. Иногда упрощает почти до уровня C# Async CTP: "A potted guide to stackless coroutines".
Вам не кажется, что код на boost::asio получается очень переусложнённым?
шаблоны в с++ вам тоже кажутся сложными? - тогда проходите мимо ;)
Мое мнение таково: task-based параллелизм пока довольно сложен и не дает достаточно преимуществ, чтобы быть однозначным лидером.
а как на счет того, чтоб использовать для подобных задач boost.phoenix+OpenMP ;)
нет, конечно, найдутся и те, кто скажет что это все сложно.. ответ - пишите на пыхыпы
Здравствуйте Марат!
Я хотел просто поблагодарить Вас, за примеры использования BOOST::ASIO, за Ваше время и советы.. Я пока только начинаю разбираться в теме, но уже в восторге от ASIO, да и от BOOSTa тоже. До этого возможности перейти на буст не было, в связи со спецификой работы.
Ещё раз БОЛЬШОЕ СПАСИБО Марат!
а как на счет того, чтоб использовать для подобных задач boost.phoenix+OpenMP
К сожалению, OpenMP я не знаю. По тому, что встречалось, складывается ощущение, что OpenMP отлично подходит для распараллеливания вычислительных задач - task-based/event-driven логику (game engine) на нем не построишь (разве что местами использовать).
Все, что видел, по сути сводится к parallel for. Этого очень мало (например, не хватает continuations). Cilk Plus мне кажется гораздо гибче и интереснее.
От коллег слышал, что OpenMP + MPI - это что-то вроде стандарта де-факто для кластерных вычислений.
OpenMP отлично подходит для распараллеливания вычислительных задач - task-based/event-driven логику (game engine) на нем не построишь (разве что местами использовать).
не очень понял смысл предложения...
(например, не хватает continuations)
это что?
Cilk Plus мне кажется гораздо гибче и интереснее.
впервые слышу о таком.. спасибо. ознакомлюсь.
не очень понял смысл предложения...
Я как-то плохо выразился. Пожалуй вот это по-лучше - Generic Parallel Algorithms in
Intel Threading Building Blocks см. Family Tree.
это что?
Asynchronous Fork/Join using Asio.
Отправить комментарий