Я немного запутался в требованиях с точки зрения безопасности потоков, размещенных в std::promise::set_value().
Эффекты: атомарно сохраняет значение r в общем состоянии и делает это состояние готовым
Тем не менее, он также говорит, что promise::set_value() может использоваться только для установки значения один раз. Если он вызывается несколько раз, std::future_error. Таким образом, вы можете установить значение обещания только один раз.
И действительно, почти каждый учебник, пример кода в сети или фактический вариант использования для std::promise включает канал связи между двумя потоками, где один поток вызывает std::future::get(), а другой поток вызывает std::promise::set_value().
Я никогда не видел случая использования, когда несколько потоков могли бы вызывать std::promise::set_value(), и даже если бы они это делали, все, кроме одного, вызывали бы исключение std::future_error.
Так почему же стандартный мандат, который вызывает std::promise::set_value() является атомарным? Каков вариант использования для одновременного вызова std::promise::set_value() из нескольких потоков?
РЕДАКТИРОВАТЬ:
Так как ответ с наибольшим количеством голосов здесь на самом деле не отвечает на мой вопрос, я предполагаю, что то, что я спрашиваю, неясно. Итак, чтобы уточнить: я в курсе, что такое будущее и обещания и как они работают. У меня вопрос, почему, в частности, стандарт настаивает на том, что std::promise::set_value() должен быть атомарным? Это более тонкий вопрос, чем "почему не должно быть гонки между вызовами promise::set_value() и вызовами future::get() "?
На самом деле, многие ответы здесь (неправильно) отвечают, что причина в том, что если std::promise::set_value() не является атомарным, то std::future::get() потенциально может вызвать состояние гонки. Но это не так.
Единственное требование избегать условия гонки - это то, что std::promise::set_value() должна иметь отношение " происходит до" с std::future::get() - другими словами, должно быть гарантировано, что когда std::future::wait() возвращает, std::promise::set_value() завершено.
Это полностью ортогонально тому, что std::promise::set_value() сам по себе является атомарным или нет. В типичной реализации, использующей условные переменные, std::future::get()/wait() будет ожидать условную переменную. Затем std::promise::set_value() может std::promise::set_value() выполнять любые произвольно сложные вычисления, чтобы установить фактическое значение. Затем он уведомил бы переменную общего условия (подразумевающую ограничение памяти с семантикой выпуска), и std::future::get() проснулся бы и безопасно прочитал результат.
Таким образом, std::promise::set_value() само по себе не обязательно должно быть атомарным, чтобы избежать здесь условия гонки - оно просто должно удовлетворять отношению "происходит до" с std::future::get().
Итак, еще раз, мой вопрос: почему стандарт C++ настаивает на том, что std::promise::set_value() должна быть атомарной операцией, как если бы вызов std::promise::set_value() был выполнен полностью в блокировка мьютекса? Я не вижу причин, по которым это требование должно существовать, если только не существует какой-либо причины или std::promise::set_value() использования для нескольких потоков, вызывающих std::promise::set_value() одновременно. И я не могу придумать такой вариант использования, отсюда и этот вопрос.