Повысить будущие продолжения (затем) тупик

В настоящее время я использую Boost 1.55 на Windows с BOOST_THREAD_VERSION=2, BOOST_THREAD_PROVIDES_FUTURE, а также BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION,

В модульном тесте продолжение, похоже, ведет себя само по себе, но в реальном коде оно блокируется.

Базовая структура кода выглядит так на стороне производителя:

typedef std::map<std::string, std::string> Dictionary;

struct Operation
{
std::unique_ptr<boost::promise<Dictionary>> m_promise;

boost::future<Dictionary> Start(const Dictionary& data)
{
m_promise.reset(new boost::promise<Dictionary>());
// pass off work to something else
//   it runs asynchronously then calls Complete
return m_promise->get_future();
}

void Complete(const Dictionary& result)
{
m_promise->set_value(result);
m_promise.reset();
}
};

И потребительская сторона выглядит так:

m_Operation.Start(data).then([=](boost::future<Dictionary> f)
{
// ...
DoSomething(f.get());
});
return true;

Продолжение вызывается, но f.get() блокирует на неопределенный срок, как и set_value,

Насколько я могу сказать, один поток заблокирован внутри promise::set_value (в частности, в future_async_shared_state_base::join()), а другой заблокирован в future::get() (в частности, мьютекс в shared_state_base::wait()).

(Похоже на нить, которая находится в set_value() пытается уничтожить продолжение после приобретения того же мьютекса, который get() заблокирован.)

Это ошибка, исправленная в более поздней версии Boost, я использую неподдерживаемую конфигурацию или я делаю что-то еще неправильно?

Я не хочу, чтобы что-либо вовлеченное блокировало, по любой причине. Это должен быть просто обратный вызов & сдавать.

Также я озадачен, почему продолжение выполняется в отдельном потоке, а не внутри set_value, Кажется, что ни одна из возможных политик запуска не поддерживает синхронное выполнение продолжения, что, как я полагаю, будет естественным заданием по умолчанию (именно так в конечном итоге ведут себя задачи .NET). Я действительно предпочел бы, чтобы он не запускал новую ветку только для запуска продолжения, так как в конечном итоге это просто отправляет работу в службу Asio.

Или фьючерсы — просто неправильная модель для такого рода вещей? Вместо этого я попытался создать асинхронный метод Asio, но быстро заблудился в шаблоне.

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]