std :: future의 상태 가져 오기


82

std::future완료 여부를 확인할 수 있습니까? 내가 할 수있는 유일한 방법은 wait_for기간이 0 으로 전화를 걸어 상태가 있는지 확인하는 것입니다 ready.하지만 더 좋은 방법이 있습니까?


10
@CatPlusPlus 내가 착각하지 않는 한 valid, 미래가 공유 상태인지 확인합니다 (즉 , 미래에 호출 true될 때까지 반환 됨 get).
David Brown

그래서, get호출되고 저장된 값을 반환한다면, 당신은 여전히 true원합니까? (한 번만 값을 얻을 수 있기 때문에이 유용 할 이유를 잘 모르겠어요.)
제임스 McNellis

@JamesMcNellis 아마도 나는 미래를 오해하거나 오용하고 있지만 내가 원하는 것은 스레드 (또는 계산을 수행하는 모든 것)가 완료되었는지 여부를 아는 것입니다. QFuture::isFinished기본적으로 Qt와 동일 합니다.
데이비드 브라운 (David Brown)

1
시간 제한이없는 대기는 많은 플랫폼에서 대부분의 API가 이러한 개념을 처리하는 방법입니다. 그래서 저는이 개념에 접근하는 "표준"방법이라고 생각합니다. 이 ... 조금 "더 나은 방법"의 개념에 의아해 날 수 있습니다
asveikau

16
@asveikau 나는 이것이 표준 관행이라는 것을 몰랐습니다. 기다리지 않을 때 wait 함수를 호출하는 것이 이상하게 느껴집니다.
David Brown

답변:


84

당신은 정확 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; }

NB 함수가 지연되면 true를 반환하지 않으므로 wait_for특정 시간이 지난 후 또는 시스템 부하가 낮을 때 지연된 작업을 동 기적으로 실행하려는 경우 직접 확인하는 것이 좋습니다 .


2
wait_for는 future를 변경하지 않으므로 매개 변수를 const로 선언 할 수 있습니다.
Jens Åkerblom 2014 년

7
get이 이미 호출되었거나 future가 초기화되지 않은 경우 런타임 오류를 방지하려면 먼저 valid ()를 확인하는 것이 좋습니다.
Jeremy Sorensen

5
wait_for (chrono :: seconds (0))가 즉시 반환되도록 보장됩니까? 아니면 일부 구현에서 몇 밀리 초 동안 스레드 제어를 양보 할 수 있습니까? 이 ... 밀리 초 몇 게임을 코딩 많은 시간이로 알고 매우 중요 할 것입니다
kynnysmatto

9
@kynnysmatto, 일부 구현에서 미래의 상태를 안전하게 검사하기 위해 뮤텍스 잠금을 획득하므로 해당 잠금이 경쟁하면 (다른 스레드가 상태를 준비하거나 준비 상태를 확인하기 때문에) 차단되고 다른 스레드 실행될 수 있지만 좋은 구현에서는 뮤텍스가 몇 개의 명령 이상을 유지해서는 안되므로 1 밀리 초도 안됩니다. GCC의 현재 구현은 뮤텍스를 전혀 사용하지 않지만 이전 구현은 두 개의 포인터를 교환하여 상태를 준비하는 것으로 완료되므로 뮤텍스는 매우 잠깐 동안 만 잠 깁니다.
조나단 Wakely

@JonathanWakely g ++ 테스트는 for(int i = 0; i < 1000; i++) f.wait_for(chrono::seconds(0));벽시계 시간 43ms가 걸립니다.
Daniel Kinsman

14

std :: future 에 대한 작업 에는 is_ready 멤버 함수 있습니다. 그 동안 VC 구현에는 _Is_ready () 멤버가 있습니다.


_Is_ready () 멤버 함수는 스레드로부터 안전하지 않습니다. 보호되지 않는 방식으로 관련 상태의 _Ready 플래그에 액세스합니다. 이것은 적어도 VS2019 16.2의 경우입니다.
Mattias De Charleroy

9

첫 번째 방법은 wait_for기간이 0 인 콜 을하고 future_status::ready, future_status::deferred또는 중 하나가 될 수있는 결과 코드를 확인하는 것입니다 future_status::timeout.

에서 cppreference 그들은 그 주장 valid() 결과를 사용할 수있는 경우 검사를 하지만, 표준은 말한다 valid()반환 true하는 경우 *this공유 상태를 말한다 그 상태인지 여부를 독립적으로, 준비 여부.


7
cppreference가 업데이트되었으며 "미래가 공유 상태인지 확인"이라고 표시됩니다. (두 번째 단락을 제거하거나 편집 할 것인지 확실하지 않으므로 직접 수정하지 않겠습니다).
기본적으로
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.