std::promise
Вот и кончилось лето. Бредут грустные детишки с рюкзаками на мощных плечах. Звенит звонок для школьников.
Впереди только холод, тьма и каторжный труд за два миска риса и одна кошка-жена. Звенит напоминание о скором митинге для разработчиков.
Долгожданные, обожаемые всеми созвоны с экспертами, в своем познании настолько преисполнившимися, что они уже как будто изучили сто триллионов миллиардов плюсовых стандартов, и им этот python абсолютно понятен, а третьего дня в расте они искали только одного - покоя, умиротворения и вот этой гармонии от слияния с бесконечно вечным, от созерцания великого фрактального подобия и от вот этого замечательного cargo...
Тяжело слушать душнину и непрошеные советы. Чтоб не задействовать обсценную лексику, я начинаю нервно ковырять объекты стандартной библиотеки. Потом расковырянное несу в freeRTOS, чтоб заценить, как оно смотрится на слабеньких армах. Вот оттуда и взялась тема с std::allocator_arg.
Упав глубоко в future, я нашел там класс _Result_alloc. Название его явно указывает, что результирующий объект может быть создан при активном содействии аллокатора.
При этом в самом классе future никаких особых конструкторов нет. Видимо, он нам не доверяет или сомневается, знаем ли мы сами, чего хотим, зачем нам аллокатор?
Будто девушка, которая делает вид, что не понимает ваших прозрачных намеков.
"Какое кино? Я в кино не хожу, смотрю только фильмы новой французской волны..."
"К тебе? Коллекцию марок? Не очень интересно, вот если бы вкладыши от Турбо..."
Раз так, нужно искать обходные пути. Например, через друзей!
Давайте заглянем в записную книжку нашего future, чтоб отыскать его приятелей:
friend class promise<_Res>;
template<typename> friend class packaged_task;
Вот кореша, способные нам помочь. Не с девушкой, конечно. Ну если только она не фанатка колхозных реализаций STL.

Как мы хорошо видим в стандарте, в разделе 33.10.6 Class template promise [futures.promise], promise не стесняется якшаться с аллокаторами:
template<class R>
class promise {
public:
promise();
template<class Allocator>
promise(allocator_arg_t, const Allocator& a);
...

Этот прекрасный класс нужен для передачи значений или исключений между потоками. Для этого он создает скрытый объект - некое разделяемое состояние. Вот второй конструктор как раз и использует аллокатор для выделения памяти под это дело.
Думаю, большинство пользователей promise пользуют его одинаково.
Создают promise, через get_future() истребуют связанный future. Дальше объект promise нужно вытеснить в рабочий поток.
В том потоке чаще всего нужно только отдать ему готовое значение.
С аллокатором будет все то же самое:
int main() {
SimpleAllocator<int> my_alloc {};
std::promise<int> promise{std::allocator_arg, my_alloc};
std::future<int> future = promise.get_future();

std::thread t(do_computation, std::move(promise));

int result = future.get(); // поток заблокирован до вызова set_value
t.join();
return result;
}

В функции do_computation через метод set_value устанавливаем значение, которого ждут в первом потоке. Либо можно пробросить исключение, если что-то пошло не так.
void do_computation(std::promise<int> p) {
std::this_thread::sleep_for(std::chrono::seconds(1));
try {
p.set_value(42);
} catch (...) {
p.set_exception(std::current_exception());
}
}

Для embedded важно вовремя использовать аллокаторы. Порой бывает так, что отличный класс стандартной библиотеки остается не у дел, потому как работает только с динамическим выделением памяти. В этом плане std::promise молодец. Только интересно, как же promise манипулирует future, заставляя его алокаториваться?
Просмотры: 43
Открыть в MAX Сообщить о неточности

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

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

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

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

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

Перейти