Вопрос по c++11, c++, multithreading – Получить статус std :: future

60

Можно ли проверить, еслиstd::future закончил или нет? Насколько я могу сказать, единственный способ сделать это будет позвонитьwait_for с нулевой продолжительностью и проверьте, если статусready или нет, но есть ли лучший способ?

@CatPlusPlus Если я не ошибаюсь,valid только проверяет, есть ли у будущего общее состояние (то есть возвращаетсяtrue до тех порget называется на будущее). David Brown
Проверитьvalid? Cat Plus Plus
Так что еслиget был вызван и возвращает сохраненное значение, вы все еще хотитеtrue? (Я не уверен, почему это было бы полезно, поскольку вы можете получить значение только один раз.) James McNellis
Ожидание с нулевым тайм-аутом - это то, как большинство API на многих платформах имеют дело с такой концепцией ... Настолько, что я бы посчитал это "стандартным". способ подхода к концепции. Это заставляет меня немного озадачиться идеей «лучшего способа» ... asveikau
@asveikau Я не знал, что это стандартная практика. Просто странно вызывать функцию ожидания, когда я не хочу ждать. David Brown

Ваш Ответ

3   ответа
7

Моя первая ставка была бы позвонитьwait_for с длительностью 0, и проверьте код результата, который может быть одним изfuture_status::ready, future_status::deferred или жеfuture_status::timeout.

Вcppreference они утверждают, чтоvalid() checks if the result is availableно стандарт говорит чтоvalid() вернусьtrue если*this относится к общему состоянию независимо от того, является ли это состояниеready или нет.

Теперь cppreference обновлен и сообщает «проверяет, есть ли у будущего общее состояние». (Не уверен, хотите ли вы удалить второй абзац или отредактировать его, поэтому я не буду изменять его сам).
55

Вы правы и кроме звонкаwait_until со временем в прошлом (что эквивалентно) лучшего способа нет.

Вы всегда можете написать небольшую оболочку, если вы хотите более удобный синтаксис:

template<typename R>
  bool is_ready(std::future<R> const& f)
  { return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready; }

Нотабене если функция отложена, она никогда не вернет true, поэтому лучше проверитьwait_for непосредственно в том случае, если вам может потребоваться запустить отложенную задачу синхронно по истечении определенного времени или при низкой загрузке системы.

Попробуйте сначала проверить valid (), чтобы избежать ошибок во время выполнения, если get уже был вызван или будущее никогда не инициализировалось.
wait_for не изменяет будущее, поэтому параметр может быть объявлен как const.
Гарантируется ли немедленное возвращение wait_for (chrono :: seconds (0)) или он может дать контроль над потоком в течение нескольких миллисекунд в некоторых реализациях? Это было бы очень важно знать, так как несколько миллисекунд - это много времени при написании кода ...
@kynnysmatto, в некоторых реализациях он получает блокировку мьютекса, чтобы безопасно проверить состояние будущего, поэтому, если эта блокировка установлена (поскольку другой поток готовит состояние или также проверяет готовность), он блокирует и другой поток может выполняться, но при хорошей реализации мьютекс никогда не должен удерживаться более чем на нескольких инструкциях, то есть даже на одну миллисекунду. Текущая реализация GCC вообще не использует мьютекс, но предыдущий применил и готовность состояния делается путем замены двух указателей, так что мьютекс блокируется очень ненадолго, пока это происходит.
8

Есть функция-член is_readyв работах для STD :: будущее. Между тем, реализация VC имеет член _Is_ready ().

Похожие вопросы