2016-05-09 4 views
3

Я не очень хорошо знаком с асинхронным программированием, и у меня есть вопрос.Boost.asio и асинхронная цепь, unique_ptr?

Мой вопрос следующий. Учитывая echo_server пример здесь для C++ 11 в Boost.Asio: http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/example/cpp11/spawn/echo_server.cpp

Я хотел бы знать, если std::make_shared<session> может быть заменен на C++ 14 с std::unique_ptr<session> в C++ 14, избегая накладных расходов ссылки сосчитать.

Я не уверен, так как мы имеем shared_from_this() но не что-то вроде unique_from_this(), так как я могу получить доступ к unique_ptr<session> внутри this?.

+0

Вы знаете, что накладные расходы - это один указатель дополнительной памяти на экземпляр и счетчик ссылок на совместное создание и удаление ptr - в противном случае это точно так же, как обычный указатель. Также неясно, к какой shared_ptr вы обращаетесь, поскольку в этом примере несколько. – xaxxon

+2

Концепция «unique_from_this» даже не имеет смысла. Вы не можете просто создать уникальный указатель на адрес памяти произвольно, так как у вас будет условие гонки относительно того, кто очистил память. – xaxxon

ответ

2

Нет, использование shared_ptr в программировании asio является идиоматическим.

Идея состоит в том, что количество выдающихся обработчиков согласовано с общим счетом объекта, инициирующего операции async. Это достигается путем связывания копии объекта shared_ptr с объектом объекта-обработчика.

С ++ 11/14 будет заменять boost::shared_ptr на std::shared_ptr (std::bind, lambdas и т. Д. Также отлично работает с asio).

Update, теперь, когда я полностью понимаю вопрос:

В примере вы связаны, я понимаю, что вы имеете в виду shared_ptr под названием самости, которая создается в методе Go()? Вы можете написать его без shared_ptr, если хотите. Вам нужно будет удалить это как последнюю строку go(). Вы также должны помнить, чтобы поймать какие-то исключения, чтобы убедиться, что этот путь кода был принят. Конечно, можно было бы установить unique_ptr, чтобы сделать это, но тогда у вас возникла проблема управления жизненным циклом между построением сеанса и успешным созданием метода unique_ptr. shared_ptr облегчает бремя управления стоимостью одного атома ...

В этом случае ответ строго «да», но imho я посоветовал, поскольку он более хрупкий.

+0

Как я понимаю, ваш объект сеанса будет проходить через конвейер обработчиков по одному за раз.Состояние вашей сессии никогда не используется. Почему unique_ptr не имеет смысла? Дело в том, что когда последний обработчик закончен, память будет выпущена. Это верно? –

+0

Последний или последний? Если есть какие-либо выдающиеся обработчики, которые связаны с сеансом, все они в конечном итоге будут срабатывать (даже если они отменены в результате уничтожения сокета). Вы можете сохранить ручное количество выдающихся обработчиков и удалить сеанс, когда он достигнет нуля, но почему? Shared_ptr делает именно это, практически без накладных расходов. –

+0

Если есть сеанс, в цикле asio все еще работает. Это не закончится. Итак, если я не ошибаюсь, произойдет следующее: если вы используете unique_ptr для каждой из сессий, только когда больше нет работы, цикл завершится. Я согласен, что накладные расходы могут быть низкими, это скорее вопрос теории :) –

0

Как я понимаю, ваш объект сеанса будет проходить через конвейер обработчиков по одному за раз. Состояние вашей сессии никогда не используется. Почему unique_ptr не имеет смысла? Дело в том, что когда последний обработчик закончен, память будет выпущена. Это верно?

Да, это трюк. Библиотека была разработана вокруг копируемых обработчиков завершения.

Если вы беспокоитесь о накладных расходах, действительно избегайте shared_ptr.

В этом случае просто передайте ссылку на какое-либо состояние с временем жизни, контролируемым извне. Просто убедитесь, что он остается живым (так же, как и с самим объектом io_service).

+0

Я понимаю это, но это не отвечает на мой оригинальный вопрос, а именно: могу ли я использовать unique_ptr и делать unique_pr, который будет автоматически переноситься, пока сам сеанс не умрет? –

+0

Если вы это поняли, то почему [вы спросили] (http://stackoverflow.com/questions/37109220/boost-asio-and-asynchronous-chain-unique-ptr/37109892?noredirect1_comment61761197_37109300)? Кроме того, я не знаю, как ответить более четко. [Является ли 'std :: unique_ptr' скопированным] (http://en.cppreference.com/w/cpp/memory/unique_ptr)? Если нет, то использование его в обработчиках завершения напрямую невозможно, и в лучшем случае это будет kludge, когда «перепечатано» с косвенным обращением. Мой совет в моем ответе. – sehe

+0

В C++ 14 вы можете захватить [my_ptr = move (my_ptr)], но я задавался вопросом, есть ли какие-либо проблемы. Большинство обеспокоены «уникальным_from_this()» или похожим, поэтому я задавался вопросом, действительно ли это можно достичь: замените unique_ptr и получим что-то подобное. –