Время жизни обещания и set_value_at_thread_exit ⇐ C++
-
Anonymous
Время жизни обещания и set_value_at_thread_exit
Предположим, у нас есть следующий код:
std::promise обещание; авто будущее = обещание.get_future(); const auto Task = [](автообещание) { пытаться { обещание.set_value_at_thread_exit(int_generator_that_can_throw()); } ловить (...) { обещание.set_Exception_at_thread_exit(std::current_Exceptionion()); } }; std::thread thread(задача, std::move(обещание)); // используем будущее поток.join(); Интересно, корректен ли и безопасен ли этот код, а если нет, то почему.
Похоже, что он работает нормально при компиляции с помощью GCC, но дает сбой (сообщение не выводится) при компиляции с помощью MSVC (2017). Я предполагаю, что сбой происходит из-за того, что локальная переменная promise внутри task выходит за пределы области видимости и уничтожается слишком рано. Если я удалю суффиксы _at_thread_exit, этот код будет работать так, как ожидалось (или, похоже, работает). Это также работает правильно, когда обещание перехвачено:
const auto Task = [p = std::move(promise)]() mutable { /*...*/ }; Полный компилируемый пример
Предположим, у нас есть следующий код:
std::promise обещание; авто будущее = обещание.get_future(); const auto Task = [](автообещание) { пытаться { обещание.set_value_at_thread_exit(int_generator_that_can_throw()); } ловить (...) { обещание.set_Exception_at_thread_exit(std::current_Exceptionion()); } }; std::thread thread(задача, std::move(обещание)); // используем будущее поток.join(); Интересно, корректен ли и безопасен ли этот код, а если нет, то почему.
Похоже, что он работает нормально при компиляции с помощью GCC, но дает сбой (сообщение не выводится) при компиляции с помощью MSVC (2017). Я предполагаю, что сбой происходит из-за того, что локальная переменная promise внутри task выходит за пределы области видимости и уничтожается слишком рано. Если я удалю суффиксы _at_thread_exit, этот код будет работать так, как ожидалось (или, похоже, работает). Это также работает правильно, когда обещание перехвачено:
const auto Task = [p = std::move(promise)]() mutable { /*...*/ }; Полный компилируемый пример
Мобильная версия