Uzyskaj status std :: future


83

Czy można sprawdzić, czy std::futureskończył się, czy nie? O ile wiem, jedynym sposobem byłoby zadzwonić wait_forz zerowym czasem trwania i sprawdzić, czy status jest, readyczy nie, ale czy jest lepszy sposób?


10
@CatPlusPlus O ile się nie mylę, validsprawdza tylko, czy przyszłość ma stan współdzielony (tj. Powraca, truedopóki nie getzostanie wywołana w przyszłości).
David Brown

Więc jeśli getzostał wywołany i zwraca przechowywaną wartość, czy nadal chcesz true? (Nie jestem pewien, dlaczego miałoby to być przydatne, ponieważ wartość można uzyskać tylko raz.)
James McNellis,

@JamesMcNellis być może nie rozumiem lub niewłaściwie wykorzystuję przyszłość, ale chcę wiedzieć, czy wątek (lub cokolwiek wykonuje obliczenia) jest zakończony, czy nie. Zasadniczo odpowiednik Qt QFuture::isFinished.
David Brown

1
Oczekiwanie z zerowym limitem czasu to sposób, w jaki większość interfejsów API na wielu platformach radzi sobie z taką koncepcją… Do tego stopnia, że ​​uznałbym to za „standardowy” sposób podejścia do tej koncepcji. Trochę mnie to
zdziwiło

16
@asveikau Nie wiedziałem, że to standardowa praktyka. Po prostu dziwne jest wywoływanie funkcji oczekiwania, kiedy nie chcę czekać.
David Brown

Odpowiedzi:


85

Masz rację i oprócz dzwonienia wait_untilz czasem w przeszłości (co jest równoważne) nie ma lepszego sposobu.

Zawsze możesz napisać małe opakowanie, jeśli chcesz wygodniejszej składni:

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

Uwaga: jeśli funkcja jest odroczona, nigdy nie zwróci ona wartości true, więc prawdopodobnie lepiej sprawdzić wait_forbezpośrednio w przypadku, gdy chcesz uruchomić odroczone zadanie synchronicznie po upływie określonego czasu lub gdy obciążenie systemu jest niskie.


2
wait_for nie zmienia przyszłości, więc parametr może być zadeklarowany jako const.
Jens Åkerblom,

7
Rozważ najpierw sprawdzenie valid (), aby uniknąć błędów w czasie wykonywania, jeśli get zostało już wywołane lub przyszłość nigdy nie została zainicjowana.
Jeremy Sorensen

5
Czy wait_for (chrono :: seconds (0)) gwarantuje natychmiastowy powrót, czy też może zapewnić kontrolę nad wątkiem przez kilka milisekund w niektórych implementacjach? Byłoby to bardzo ważne, ponieważ kilka milisekund to dużo czasu podczas kodowania gry ...
kynnysmatto.

9
@kynnysmatto, w niektórych implementacjach uzyskuje blokadę mutex, aby bezpiecznie sprawdzić stan przyszłości, więc jeśli ta blokada jest brana pod uwagę (ponieważ inny wątek przygotowuje stan lub również sprawdza gotowość), to zostanie zablokowany, a kolejny wątek może działać, ale przy dobrej implementacji mutex nie powinien być przechowywany dłużej niż przez kilka instrukcji, a więc nawet przez jedną milisekundę. Obecna implementacja GCC w ogóle nie używa muteksu, ale poprzednia tak, a przygotowanie stanu odbywa się poprzez zamianę dwóch wskaźników, więc mutex jest blokowany tylko na bardzo krótko, kiedy to się dzieje.
Jonathan Wakely

@JonathanWakely testowanie za pomocą g ++ for(int i = 0; i < 1000; i++) f.wait_for(chrono::seconds(0));zajmuje 43 ms czasu zegara ściennego.
Daniel Kinsman

15

W pracach dla std :: future istnieje funkcja składowa is_ready . W międzyczasie implementacja VC ma element członkowski _Is_ready ().


Zauważ, że funkcja składowa _Is_ready () NIE jest bezpieczna wątkowo. Uzyskuje dostęp do flagi _Ready skojarzonego stanu w sposób niestrzeżony. Tak jest przynajmniej w przypadku VS2019 16.2.
Mattias De Charleroy

10

Mój pierwszy zakład byłoby zadzwonić wait_forz 0 trwania, i sprawdzić kod wynik, który może być jednym z future_status::ready, future_status::deferredlub future_status::timeout.

W cppreference twierdzą, że valid() sprawdza, czy wynik jest dostępny , ale standard mówi, że valid()zwróci, truejeśli *thisodnosi się do wspólnego stanu, niezależnie od tego, czy ten stan jest gotowy, czy nie.


7
cppreference zostało zaktualizowane i stwierdza, że ​​„sprawdza, czy przyszłość ma wspólny stan”. (Nie jestem pewien, czy chcesz usunąć drugi akapit, czy go edytować, więc sam go nie zmodyfikuję).
Domyślnie
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.