| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Вопрос по boost::asio |
| Автор: Artemon 26.2.2011, 16:10 |
| Наслышан о том что с помощью asio можно написать сервер, который при прочих равных условиях выдержит большее число подключений чем сервер работающий по модели ОДИН КЛИЕНТ-ОДИН ПОТОК. Вопрос: Есть машинка с одноядерным процессором, на сервере производится длительная операция обращения к БД. Как в asio сделать так чтобы пока идет работа с БД - остальные клиенты не проставивали ? P.S. С многопоточным сервером все понятно, пока идет длительная операция - остальные потоки работают, разделяя общее процессорное время. |
| Автор: Abyx 26.2.2011, 17:20 |
| выносить операцию с бд в поток %) я хз как связана ваша бд и asio |
| Автор: bsa 26.2.2011, 20:14 |
| Artemon, asio - это аббревиатура от асинхронного ввода вывода. Там смысл несколько отличный от стандартных представлений. Если тебе надо что-то сделать, то ты вызываешь соответствующий метод передавая ему функтор, который должен быть вызван по завершении операции. Когда операция завершается, этому функтору передается код завершения (ok или ошибка). И ты из этого функтора уже заказываешь выполнение следующего действия... Таким образом, ты никогда не сидишь и не ждешь, пока выполнится какое-либо действие - в это время может выполняться другое. Например, у тебя есть твой вэб-сервер, работающий с БД. При запуске сервера ты ставишь задачу: установить TCP соединение с сервером БД И запускаешь io_service.run()... Как только у тебя происходит установка связи с БД вызывается соответствующий функтор, и если все в порядке, ты посылаешь команду авторизации... После ее отправки ты ставишь задачу ожидания результата авторизации. В случае успешного результата ты отправляешь команду на открытие БД... Короче, работа с БД установлена. Теперь можно открыть TCP порт 80 в режиме приема соединений, ставишь соответствующую задачу. При подключении очередного клиента ты опять ставишь задачу приема соединений, а так же задачу получения от него данных. Когда ты их получишь, ты ставишь задачу оправки запроса к БД... В это же время может быть принят другой клиент... |
| Автор: bsa 26.2.2011, 22:14 |
| Artemon, раз ты такие вопросы задаешь, значит ты не понимаешь, как работает asio. постановка задачи занимает практически нулевое время. Другими словами, функция постановки возвращается тут же. Долгий запрос будет выполняться в "фоне". Т.е. ты не должен ждать, когда он завершится. Ты поставил задачу отправить запрос к БД и все. Когда задача будет выполнена будет вызвана твоя функция, в которой ты только поставишь задачу "принять данные от БД" и все. После успешного приема данных от БД, ты ставишь задачу "отправить данные клиенту"... Посмотри внимательно примеры под asio. |
| Автор: Artemon 26.2.2011, 23:05 | ||
| насколько я понял у asio есть 2 основных метода sync_read и sync_write в которые мы передаем методы, которые выполнятся по завершению чтения или записи. Допусти я сделал что-то типа этого:
Когда завершится чтение - начнет выполняться метод ReadHandler. Но с чего это он будет выполняться в Фоне ? |
| Автор: boostcoder 27.2.2011, 00:35 | ||||
нет. есть синхронные(блокирующие): read() и write(). и есть асинхронные(не блокирующие): async_read() и async_write().
по хорошему, должен быть пул потоков в котором выполняется asio::io_service::run. в таком случае, если пул интеллектуальный, он сам, в зависимости от thread_sleep_time(не знаю как на русском сказать), производит регулирование числа потоков. при этом, вы, свой долгий_запрос_к_БД, можете запостить как любую асинхронную задачу. смотрите: http://www.boost.org/doc/libs/1_46_0/doc/html/boost_asio/reference/io_service/post.html это позволит интеллектуальному пулу потоков, учитывать время затрачиваемое на этот запрос. и он(интеллектуальный пул потоков) примет этот факт во внимание, и в зависимости от политики пула, он, возможно, будет добавлять/убавлять кол-во потоков.
не понял вопроса.. |
| Автор: bsa 27.2.2011, 12:36 | ||
Artemon, ты все перепутал.
|
| Автор: Artemon 27.2.2011, 18:30 | ||||
boostcoder,
Подозреваю что эта асинхронная задача будет реализовываться с помощью потока. Если для каждого клиента создавть такие задачи, то какой выигрышь от ухода от модели один клиент-один поток? На счет интеллектуальности - для начала хотелосьбы разобраться, удастся реализовать сервер используя лишь один основной поток + асинхронные вызовы asio.
Каким образом данная строка выполнится асинхонно ? Как раз таки я и думаю что затык будет именно в этом месте (возможно ошибаюсь). |
| Автор: boostcoder 27.2.2011, 18:47 | ||
RTFM |
| Автор: bsa 27.2.2011, 20:35 |
| Artemon, основное время при работе по сети расходуется на ожидание ответа от удаленной машины. Это может делать как ядро системы, так и приложение. Отличия только в том, какой вызов используется. Есть синхронный, а есть асинхронный. Отличия в том, что если первый ждет завершения выполнения операции, то второй не ждет. При завершении операции приходит определенный сигнал. Вот asio с этим и работает. |
| Автор: xvr 28.2.2011, 16:54 |
| asio не позволяет выполнять какую то работу параллельно с другой работой, она позволяет выполнять ввод/вывод параллельно с другой работой. Что бы обращение к BD было асинхронным, оно должно быть оформлено в виде отправки запроса через сеть (например запись текста SQL запроса в пайп), и дальнейшего чтения ответа опять же через сеть. В таком случае asio позволит время от отправки запроса и до получения ответа использовать для обслуживания других клиентов |
| Автор: boostcoder 28.2.2011, 18:47 | ||
во первых - зачем? во вторых - а если БД локальная, какой смысл в interprocess-comunication? |
| Автор: xvr 28.2.2011, 23:07 | ||||||
Это вопрос к ТС, а то он пытается от asio добиться каких то чудес
|
| Автор: Artemon 1.3.2011, 20:26 |
| Чудес я добиться не пытаюсь, а хочу лишь понять насколько реально сделать сервер на asio, под сервером я НЕ имею ввиду простейшие чаты, эхо серверы и прочее, а серьезный сервер, выполняющий сотни различных команд, делающий сложный выборки, реализующий часть логики клиентского приложения и т.д. При модели один поток-один клиент (+ блокирующие сокеты), все это можно сделать без какого-либо шаманства. Изучаю asio с его асинхронной моделью, пока собственно никаких плюсов кроме асинхронной модели не обнаружил, хотя это даже не плюс, а предпосылка к тому плюсу, что можно избавится от потоков. Тему не закрываю, хочу еще поэксперементировать и сюда запостить появившиеся вопросы. |
| Автор: boostcoder 1.3.2011, 20:33 | ||
я лишь хотет сказать, что задачу выборки из БД, можно выполнить асинхронно, при помощи asio::io_service::post() если использовать предложенный мною способ - то никакой разницы нет в том, локальная БД, или удаленная.
читать: http://forum.vingrad.ru/index.php?showtopic=323481&view=findpost&p=2306305 |
| Автор: Artemon 1.3.2011, 21:09 |
| Получется так, что каждый запрос клиента заставляет сервер лезть в БД и долго(к примеру 10 секунд) копаться с ней. Вижу следующий алгоритм работы сервера: 1. Сервер стоит и ждет подключения клиента. 2. Подключается клиент, все ok ресурсов почти не потрачено. 3. Клиент посылает серверу запрос, вот тут есть 2 варианта: a. В основном потоке сервера обратиться к БД, при этом 10 секунд все остальные клиенты ждут. b. Создать поток, в котром будет запрос к БД, собственно от чего уходили к тому и пришли. c. Использовать Post, но опятже он работает в контексте свободного потока. Можеть я еще какой-то вариант из пункта №3 пропустил ? |
| Автор: boostcoder 1.3.2011, 21:14 | ||||
все зависит от типа БД, и от того, кто ее проектировал.
а что не так? возможно вы действительно ожидаете чудес ;) |
| Автор: Artemon 1.3.2011, 21:20 |
Похоже что караз таки все так и чудест действительно не получится |