2013-09-26 2 views
0

Я унаследовал некоторый код boost :: asio, который использует асинхронные методы для чтения/записи данных с помощью некоторого сокета. В настоящее время код использует повышение :: привязку для чтения/записи обработчики функций-членов класса, как это:Каковы преимущества или недостатки использования хранимой функции boost :: function vs boost :: bind with boost :: asio?

boost::asio::async_read(socket_, boost::asio::buffer(&in_data.header.packet_size, 1), boost::bind(&SocketIO::handle_read, shared_from_this(), boost::asio::placeholders::error); 

Я хотел бы изменить код, чтобы использовать сохраненную версию связывают с использованием повышение :: функции, но я неясно, есть ли какие-либо преимущества или недостатки для этого. Я бы подумал, что не воссоздать привязку непрерывно сократит выделение объектов. Однако в дополнительной документации для async_receive (Listed Here) указано: «Копии будут сделаны из обработчика по мере необходимости». Я не уверен, какие условия потребуют сделать копию или нет.

Любое понимание этого будет оценено по достоинству.

+0

Я считаю, что он не указан в отношении условий, которые могут привести к копированию обработчика. Когда семантика перемещения недоступна, копии будут сделаны в нескольких местах в пределах Boost.Asio. Когда доступны семантика перемещения, и обработчик не является «rvalue», я полагаю, что одна копия сделана, а затем перемещена в Boost.Asio. –

ответ

0

Привязка может быть довольно эффективной, так как она может работать, даже не дойдя до кучи. Он просто копирует ваши переменные и заполнители во внутреннюю структуру стека и возвращает это. Результирующий тип довольно сложный, но вам обычно не нужно ничего видеть.

Если вы должны были хранить это в boost::function, для этого потребовалось бы какое-то распределение кучи. Это, теоретически, произойдет только один раз, но в этом случае это непрактично.

Второй аргумент для вашего звонка bind: shared_from_this(). Это отличный способ убедиться, что ваш объект не будет уничтожен до того, как будут задействованы все его обработчики, поскольку ASIO сохранит shared_ptr для вашего объекта. Проблема в том, что если вы должны были сохранить результат bind в boost::function, вы также сохранили бы общий указатель. Это приведет к тому, что всегда будет shared_ptr для вашего объекта, предотвращая надлежащее уничтожение вашего объекта.

+0

Рассматривается количество [копий аргументов, сделанных 'boost :: function'] (http://stackoverflow.com/q/14617835/1053968). Кроме того, вы можете быть осторожны с выполнением стирания стилей, чтобы уменьшить количество созданных функторов, поскольку это предотвратит использование Boost.Asio правильных 'asio_handler_ *' крючков. Это не должно быть проблемой с 'boost :: bind()', но это повлияет на обработчиков, возвращаемых из 'strand.wrap()'. –

Смежные вопросы