2016-12-16 15 views
6
#include <iostream> 
#include <string> 
#include <thread> 
#include <future> 


int main() 
{ 
    auto pms = std::promise<std::string>(); 
    auto ftr = pms.get_future(); 

    std::thread([&](){pms.set_value("hello world");});  
    ftr.wait(); 
    std::cout << ftr.get() << std::endl; 

    return 0; 
} 

Według this link, std::future::wait bloki aż wynikiem staje dostarczony.
Dlaczego nie przyszły :: wait() blokuje

Jednak powyższy kod nie może niczego wydrukować. Oczywiście główny wątek zakończył się przed zakończeniem wątku pms.set_value.

Dlaczego nie blokuje ftr.wait()?

+0

chciałbym zaproponować Ci spojrzeć na std :: asynchroniczny – LeDYoM

Odpowiedz

9

Problem nie polega na tym, że std::future::wait nie blokuje. Prawdziwy problem polega na tym, że masz problem wyścigowy między wątkiem, który zrodziłeś, wykonując jego pracę, a zniszczeniem obiektu std::thread (tymczasowego) w głównym wątku.

Z tego powodu w destruktorze std::thread jest wywoływana, jeśli wątek nadal można dołączyć.

kod robocza:

#include <iostream> 
#include <string> 
#include <thread> 
#include <future> 
#include <chrono> 

int main() 
{ 
    auto pms = std::promise<std::string>(); 
    auto ftr = pms.get_future(); 

    std::thread thread ([&](){pms.set_value("hello world");});  
    ftr.wait(); 
    std::cout << ftr.get() << std::endl; 
    thread.join(); 
    return 0; 
} 

Uwaga, jeśli nie przyłączyć się do thread wyraźnie, byś nadal mają ten sam stan Race (ponieważ jest możliwe, że main może zrobić swoją pracę szybciej, niż thread puszka oczyścić się w górę

Demo przykład pracy.. here

+3

Upvoted za nie sugeruje oderwanie nić. –

0

Alternatywnie można odłączyć i używać nici promise::set_value_at_thread_exit zamiast set_value

#include <iostream> 
#include <string> 
#include <thread> 
#include <future> 
#include <chrono> 


int main() 
{ 
    auto pms = std::promise<std::string>(); 
    auto ftr = pms.get_future(); 

    std::thread([&](){pms.set_value_at_thread_exit("hello world");}).detach();  
    ftr.wait(); 
    std::cout << ftr.get() << std::endl; 

    return 0; 
} 
Powiązane problemy