BOOST ASIO multi-io_service RPC фреймворк дизайн RFC - PullRequest
1 голос
/ 21 июля 2011

Я работаю над платформой RPC, я хочу использовать дизайн multi io_service, чтобы отделить io_objects, который выполняет IO (front-end) от потоков, которые выполняют работу RPC (back-end).

Внешний интерфейс должен быть однопоточным, а внутренний должен иметь пул потоков.Я рассматривал проект, чтобы заставить внешний интерфейс и внутренний интерфейс синхронизироваться, используя условные переменные.Однако, кажется, boost::thread и boost::asio не объединяются --ie, похоже, условная переменная async_wait поддержка недоступна.У меня есть вопрос по этому вопросу здесь .

Мне пришло в голову, что io_service::post() может использоваться для синхронизации двух объектов io_service.Я приложил диаграмму ниже, я просто хочу знать, правильно ли я понимаю механизм post, и это разумная реализация.

rpc system implementation

Ответы [ 2 ]

2 голосов
/ 22 июля 2011

Я предполагаю, что вы используете " один io_service и пул потоков, вызывающий io_service::run()"

Также я предполагаю, что ваш frond-конец является однопоточным только для того, чтобы избежатьзапись состояния гонки из нескольких потоков в один и тот же сокет.

Та же цель может быть достигнута с помощью io_service::strand ( учебник ). Ваш интерфейс может бытьMT синхронизирован по io_service::strand.Все posts от внутреннего до внешнего интерфейса (и обработчики от внешнего до внешнего типа, такие как handle_connect и т. Д.) Должны быть заключены в strand, что-то вроде этого:

back-end -> front-end:

io_service.post(front_end.strand.wrap(
    boost::bind(&Front_end::send_response, front_end_ptr)));

или front-end -> front-end:

socket.async_connect(endpoint, strand.wrap(
    boost::bind(&Front_end::handle_connect, shared_from_this(), 
    boost::asio::placeholders::error)));

И все сообщения от front-end до back-end не должны бытьзавернутый strand.

1 голос
/ 21 июля 2011

Если вы являетесь внутренним пулом потоков, вызывающих любую из функций io_service::run(), io_service::run_one(), io_service::poll(), io_service::poll_one(), и вашим обработчикам требуется доступ к общим ресурсам, вам все равно нужно позаботиться о том, чтобы как-то заблокировать эти общие ресурсы в самих обработчиках.

Учитывая ограниченный объем информации, размещенной в вопросе, я бы предположил, что это будет работать нормально с учетом вышеизложенного предостережения.

Однако при публикации есть некоторые измеримые издержки для настройки необходимых портов завершенияи ожидание - накладные расходы, которые вы могли бы избежать, используя другую реализацию своей «очереди».

Не зная точных деталей того, что вам нужно сделать, я бы посоветовал вам посмотреть на строительные блоки потоков для конвейеров или, возможно, проще для параллельной очереди .

...