back to the std::future
Привели мы как-то нашего ПМ-а в цирк. Никогда до этого не был. А там по арене наматывают круги кони, бегемот сквозь горящие кольца прыгает, на простынях под куполом гимнасты корчатся. Вот дрессированные коты ходят строем, олень на табуретке кеглями жонглирует, бегают клоуны и обливают друг друга желтой водицей. Три часа как на одном дыхании.
За время представления ПМ ни разу не улыбнулся, постоянно отвлекался, записывал что-то в телефоне.
Мы его спрашиваем:
- Не понравилось, да?
- Почему? - строго взглянул на нас. - Понравилось, спасибо.
И опять что-то в сотике набирает.
На следующий день назначает митинг про новую стратегию управления.
- Вчера, наконец-то, я понял, как должны выглядеть процессы в нашей компании, - говорит с чикатильской улыбкой, - нам нужна Continuous Incremental Resilient Collaborative User-centric Sustainable Strategy!
И открывает презентацию:
"CIRCUS Strategy — это подход к управлению разработкой, основанный на непрерывной и инкрементальной поставке ценности через устойчивую к изменениям и высококоллаборативную среду, с фокусом на потребности пользователя и сохранением стабильного темпа команды".
Три часа как на одном дыхании. В конце всем сказал поставить себе цели на год. Не к добру это.
Пока поставил себе целью разобраться окончательно в кружевах и подпорочках std::future. В прошлый раз успели только убедиться, что результат std::promise на самом деле принадлежит разделяемому состоянию. Это значит, что в отличие от депутатов, promise раздает не только обещания, но и возвращает вожделенное значение.
В роли обещания выступает объект std::future, и получить его проще, чем отказ на собеседовании.
Достаточно вызвать простой надежный советский метод get_future(), чтоб получить немного надежды на будущий результат.


future<_Res> get_future(){ return future<_Res>(_M_future); }

Для друзей у std::future есть особый конструктор:

explicit future(const __state_type& __state) : _Base_type(__state) { }

Где тип аргумента __state_type это тип разделяемого состояния и есть.

typedef shared_ptr<_State_base> __state_type;

Можно ошибочно предположить, что фьючерсы можно раздавать всем подряд, shared_ptr все стерпит. Однако взгляните на функцию извлечения:

_Res get() { typename _Base_type::_Reset __reset(*this); return std::move(this->_M_get_result()._M_value());}Метод

этот в Химках уже видели. Кажется, мы вернулись к тому, с чего начинали. Как вы хорошо помните, _Res - это тип шаблонного аргумента std::future. Возвращаем мы не просто копию объекта типа _Res, а через move отдаем владение результатом страждущему. Более того, разделяемое состояние сбрасывается через RAII __reset.
Все эти факты мягко намекают нам, что метод get одноразовый!
При повторном вызове функция проверки в методе _M_get_result бросит исключение std::future_error с кодом no_state.

template<typename _Tp>static void _S_check(const shared_ptr<_Tp>& __p) { if (!static_cast<bool>(__p)) __throw_future_error((int)future_errc::no_state);}Но ско

рее всего, так далеко мы зайти не успеем. Будем остановлены на стадии получения второго std::future.
Особый конструктор для друга у std::future есть, но он с подвохом.
Конструктор future вызывает конструктор базового класса __basic_future


explicit __basic_future(const __state_type& __state) { _State_base::_S_check(_M_state); _M_state->_M_set_retrieved_flag();}Провер

ка _S_check ничего вам не сделает, а вот _M_set_retrieved_flag...
Сей атомный флаг как раз отслеживает, передавалось ли уже это разделяемое состояние в какой-нибудь std::future. Такой интересный костыль для shared_ptr:

void _M_set_retrieved_flag() { if (_M_retrieved.test_and_set()) __throw_future_error(int(future_errc::future_already_retrieved));}Если

уже передавался, то бросаем исключение с кодом future_already_retrieved.
А, ну и цели почти во всех компаниях - это карго-культ.
Просмотры: 35
Открыть в MAX Сообщить о неточности

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти