2016-07-14 3 views
0

Ich entwickle ein Spiel. Lassen Sie uns sagen Theres ein Objekt LoadingState mit diesen Methoden (und einige andere):C++ 17 async: Ausführen einer dieser Methode blockiert das ganze Objekt

  • Update
  • Last
  • genannt

Das Update wird die CPUs Uhr tickt jedes Mal erstellen, während Das create wird nur einmal aufgerufen und sollte die Ladefunktion (asynchron) aufrufen, um einige Spiel-Assets zu laden. Der asynchrone Ladeaufruf innerhalb der create-Funktion erlaubt (theoretisch) die Aktualisierung von beling, die während des Erstellens/Ladens aufgerufen wird. Dies geschieht jedoch nicht.

Vor Visual Studio 2015, ich war mit std :: async wie folgt aus:

std::async(&LoadingState::load, this, THE_ASSETS_PATHS_STRING_VECTOR); 

Nach dem Visual Studio Migration 2015 (C++ 17) und das Lesen, dass die std :: Start muss sein angegeben ist, ansonsten ein unerwartetes Verhalten passieren könnte, ist die Asynchron jetzt so genannt:

std::async(std::launch::async, &LoadingState::load, this, THE_ASSETS_PATHS_STRING_VECTOR); 

mit anderen Worten, es sieht aus wie mir, dass ‚dies‘ durch die std :: async gesperrt wird, das ganze Objekt blockiert , verhindert, dass der Hauptthread update aufruft.

Relevanter Code:

void LoadingState::onCreate() 
{ 
    std::vector<std::string> assets; 

    assets.push_back("Images/Scenario/wall.png"); 
    assets.push_back("Images/Scenario/bigdummy.png"); 
    assets.push_back("Images/Scenario/buildings.png"); 
    assets.push_back("Images/Scenario/floor.png"); 
    assets.push_back("Images/Scenario/terrain.png"); 
    assets.push_back("Images/Scenario/trees.png"); 

    // Load assets asynchronously 
    std::async(std::launch::async, &LoadingState::load, this, assets); 
} 

void LoadingState::load(std::vector<std::string> assets) 
{ 
    unsigned int count = 0; 
    unsigned int ratio = 100U/assets.size(); 

    // Cache the asset accordingly 
    for (auto& asset : assets) 
    { 
     // Load and store the asset 
     // ... 

     // Asset loaded 
     count++; 

     // Calculate the progress by count 
     m_progress = count * ratio; 
    } 

    // If assets were skipped or progress would be like 98% due to truncation, normalize it 
    m_progress = 100U; 
} 


void LoadingState::update(float delta) 
{ 
    // ... 

    // If finished loading the resources, move on to playing state! 
    if (m_progress >= 100U) { 
     m_machine->next(new PlayingState(m_machine)); 
    } 
} 

Was bin ich Missverständnis hier ?!

PS: Alles lief früher als die Migration.

+2

Prortal zu C++ 11, ich verspreche Ihnen, dass Sie nicht 'std :: async' verwendet haben! –

+0

Auch THE_ASSETS_PATHS_STRING_VECTOR existiert nicht. Deine Kritik/Sarkasmus hat nicht geholfen. –

+1

"* Visual Studio 2015 (C++ 17) *" VS 2015 enthält kein C++ 17. Es enthält höchstens Bits von C++ 17 *. –

Antwort

1
std::async(std::launch::async, &LoadingState::load, this, assets); 

The future von asyncwill block in its destructor until the async function has finished (im Gegensatz zu jedem anderen future Objekt) zurückgegeben. Sie müssen daher müssen erfassen, dass future und halten Sie es am Leben (Verschieben, wo nötig), bis Sie für die Antwort bereit sind.

Oder Sie können einfach aufhören, il-konzipierte Funktionen wie async zu verwenden.

lesen, dass der std :: Start angegeben wird

hat

Nein, ist es nicht.

+1

'async' war nicht schlecht durchdacht. Es wurde einfach nicht richtig voreingestellt. C++ 14 hat das behoben. Sie haben das OP aus dem Zusammenhang heraus zitiert: "std :: launch muss angegeben werden, sonst könnte ein unerwartetes Verhalten auftreten." Dies gilt ab C++ 14. – Tim

+0

"Wenn weder std :: launch :: async noch std :: launch :: defered noch ein implementierungsdefiniertes Richtlinienflag in der Richtlinie festgelegt ist, ist das Verhalten nicht definiert." - http://en.cppreference.com/w/cpp/thread/async –

+1

@ YvesHenri: Und das Aufrufen der ersten Überladung ruft die zweite Überladung auf und stellt diese beiden Parameter bereit. Das ist kein undefiniertes Verhalten; das ist nur ein Standardparameter über Funktionsüberladung. –

Verwandte Themen