Использование futures в C++11: Вложенные вызовы std::async приводят к сбоям - ошибка компилятора или стандартной библиотеки?
Описание проблемы
После того как я столкнулся с падениями программы при использовании вложенных вызовов std::async
, я смог воспроизвести проблему в следующем минимальном примере. Ошибки происходят часто, но не всегда. Видите ли вы что-то, что может быть причиной проблемы, или это ошибка компилятора или стандартной библиотеки? Обратите внимание, что проблема сохраняется даже если добавить вызовы get()
для будущих значений.
#include <future>
#include <vector>
int main (int, char *[])
{
std::vector<std::future<void>> v;
v.reserve(100);
for (int i = 0; i != 100; ++i)
{
v.emplace_back(std::async(std::launch::async, [] () {
std::async(std::launch::async, [] { });
}));
}
return 0;
}
Наблюдаемые ошибки
Я наблюдаю два разных типа сбоев (примерно в каждые пятые запуски):
- Завершение с сообщением: "Это приложение запросило завершение работы Runtime в необычном режиме."
- Завершение после выбрасывания экземпляра 'std::future_error', what(): Promise already satisfied.
Окружение
- Windows 7
- gcc версии 4.8.2 (i686-posix-dwarf-rev3, построен проектом MinGW-W64), как предоставлено Qt 5.3.2
- Команда для компиляции:
g++ -std=c++11 -pthread futures.cpp
- Скомпилировано и запущено на двух независимых машинах
Вопрос о опции -pthread
Может быть, в моем окружении по какой-то причине опция -pthread
не учитывается? Я заметил одинаковое поведение как с этой опцией, так и без неё.
В чём разница между g++ и gcc?
Возможно ли вывести тип переменной в стандартном C++?
Неопределенная ссылка на виртуальную таблицу (vtable)
Почему `std::initializer_list` не поддерживает оператор подиндексации?
Стоит ли игнорировать предупреждение "-Wmissing-braces" от gcc/clang?