Уходя с бумаги об улучшениях std::future
API здесь n3721. Похоже, что в распространении исключений есть расы в отношении развернутых фьючерсов. В документе говорится
Если внешнее будущее выдает исключение, и .get () вызывается для возвращенного будущего, возвращенное будущее выдает то же исключение, что и внешнее будущее. Это так, потому что внутреннее будущее не покинуло
Так что я имею в виду в следующем случае
#include <iostream>
#include <future>
#include <exception>
using namespace std;
int main() {
auto prom_one = std::promise<std::future<int>>{};
auto fut_one = prom_one.get_future();
std::thread{[prom_one = std::move(prom_one)]() mutable {
auto prom_two = std::promise<int>{};
auto fut_two = prom_two.get_future();
std::thread{[prom_two = std::move(prom_two)]() mutable {
prom_two.set_exception(std::make_exception_ptr(std::logic_error{}));
}}.detach();
prom_one.set_exception(std::make_exception_ptr(std::bad_alloc{}));
}}.detach();auto inner_fut = fut_one.unwrap();
cout << inner_fut.get() << endl;
return 0;
}
Гонка, о которой я говорил ранее, — какое исключение будет выброшено? Внутренний std::logic_error
или внешний std::bad_alloc
?
Я правильно понял? В приведенном выше коде нет расы?
Я понял, что приведенный выше код не имеет никакой расы, так как с вложенным будущим — std::future<std::future<int>>
Есть только две возможности, либо внутреннее будущее было установлено с помощью вызова std::promise::set_value
или было установлено исключение, и внутреннее будущее вообще не связано с внешним будущим (как в коде выше).
Если внутреннее будущее не было связано, то исключение внешнего будущего будет брошенным исключением. И если внутреннее будущее было связано, то нет никакого смысла для бросания внешнего будущего, потому что обещание внешнего будущего уже вызвало set_value
с внутренним будущим один раз, поэтому установка исключения после этого для самого внешнего будущего недопустима (что приведет к созданию самого исключения).
Я думаю, что это то, о чем говорилось в газете, когда говорилось
Это так, потому что внутреннее будущее не покинуло
Других решений пока нет …