2010-02-10 1 views
2

Я создаю однопоточный сервер aync, который получает данные от клиентов. Он обрабатывает данные, а затем сохраняет их в базе данных MySQL.Использование API блокировки Mysql с Boost :: asio

Проблема заключается в том, что MySQL C API не поддерживает неблокирующие вызовы, а asio в основном не любит блокировки вызовов.

Так что я думаю что-то вроде deferToThread() Python Twisted, как семантика. Кто-нибудь, кто уже развил такую ​​вещь? Или я должен его реализовать?

+0

Это тривиально с asio, чтобы иметь нить за соединение. Вам нужен поток для каждого соединения и поток на mysql write? –

+1

Я не хочу иметь нить за соединение. Это убьет масштабируемость сервера. – serialx

ответ

2

Был a post в список рассылки Asio в течение лета, описывающий общий асинхронный класс обслуживания, который кажется им может быть полезен для вас. Этот псевдо-код от электронной почты автора я связан:

// Create a command processor with 5 threads allocated 
// to processing the commands. 
async_command_processor processor(io_service, 5); 

// Execute the command asynchronously and call the 
// MyCommandComplete callback when completed. 
processor.async_execute(MyCommand, MyCommandComplete); 
0

"огонь и забыть" нить. Вы можете создать класс с операторами() и переменными-членами с данными для записи. В обработчике данных asio accept создайте один из этих классов, а затем передайте его в поток boost. Boost thread будет КОПИРОВАТЬ этот класс внутри и запустить поток. Если вы внимательно относитесь к тому, как вы пишете оператор(), он должен завершиться, когда запись sql будет выполнена и выпустить свои данные записи. Вы можете вызвать boost :: thread :: detach, чтобы забыть о потоке и просто дать ему закончить, а затем умереть. Таким образом вы запускаете новые потоки, которые пишут mysql из ваших обработчиков asio. Я не уверен, что происходит с данными элемента, когда класс потока выходит за рамки. дважды проверьте документы повышения, может быть проблемой, если поток повышения не завершен, и поток по-прежнему нуждается в данных, которые исчезли. Возможно, здесь могут помочь общие указатели.

+0

Но я хочу вызвать обработчик, чтобы уведомить, что выполнение sql завершено. В принципе, я хочу использовать async_read для MySQL. Или общий async_call_from_other_thread_and_comeback – serialx

+0

О, я вижу сейчас. Затем вы можете использовать boost :: signals2, которые вызываются из потока «отработанных», как раз перед тем, как этот поток завершится, и соедините их при создании класса-функтора для потока. Мне нравится, насколько импульс всегда является ответом. –

3

Может быть, вы будете заинтересованы в этом на основе Asio асинхронного клиента библиотеки MySQL с именем Amy: https://github.com/liancheng/amy

Цитируется GitHub README:

Amy является совместимым с C++ 11 только заголовком A synchronous My SQL-клиентская библиотека на основе Boost.Asio. Это позволяет работать с MySQL как асинхронным, так и блокирующим способом.

+0

Пожалуйста, добавьте дополнительную информацию здесь. – hims056

+0

@ hims056 Похоже, действительно хороший код. Только заголовок использует файловые системы/program_options только для тестов. Использует параметр boost для именованных параметров (порядок в отдельном пространстве имен для ключевых слов с именованным параметром). Я искушаюсь использовать это. Просмотрите более поздно – sehe

+0

Большое спасибо Cheng Lian, очень хорошая библиотека. – Ramy