2016-07-14 72 views
0

我正在开发一款游戏。可以说,那里有一个对象LoadingState进行这些方法(和一些其他):C++ 17异步:运行这个'方法阻塞整个对象

  • 创建
  • 更新
  • 负载

的更新被称为每个CPU的时钟滴答的时间,而创建只会被调用一次,它应该调用加载函数(异步),以加载一些游戏资源。在创建函数内异步调用加载允许(理论上)从创建/加载执行时调用的beling进行更新。但是,这并没有发生。

之前到Visual Studio 2015年,我用的std ::异步那样:

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

迁移到Visual Studio 2015年(C++ 17)和阅读的标准::启动必须是经过指定,否则无法预期的行为可能发生,异步现在叫这样的:

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

换句话说,它看起来像对我说,“这”被通过的std ::异步锁定,阻止整个对象,阻止主线程调用更新。

更多相关代码:

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)); 
    } 
} 

什么我误解在这里?

PS:在迁移之前用于运行的所有东西。

+2

Priort to C++ 11,我保证你没有使用'std :: async'! –

+0

THE_ASSETS_PATHS_STRING_VECTOR也不存在。你的批评/讽刺并没有帮助。 –

+1

“* Visual Studio 2015(C++ 17)*”VS 2015不包含C++ 17。它至多包含C++ 17 *的位。 –

回答

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

asyncwill block in its destructor until the async function has finished(不像每隔future对象)返回的future。因此,您必须必须捕获future并保持活动状态(必要时移动它),直到您准备好答案为止。

或者你可以停止使用il-conceived功能,如async

阅读的标准::推出必须指定

不,不。

+1

“异步”并非构思不全。它只是没有给予适当的默认值。 C++ 14修复了这个问题。你引用OP的背景:“必须指定std :: launch,否则可能会发生意外的行为。”从C++ 14开始,情况就是如此。 – Tim

+0

“如果策略中既没有设置std :: launch :: async也没有设置std :: launch :: deferred,也没有设置任何实现定义的策略标志,则行为未定义。” - http://en.cppreference.com/w/cpp/thread/async –

+1

@YvesHenri:调用第一个重载将调用第二个重载,提供这两个参数。这不是未定义的行为;这只是一个通过函数重载的默认参数。 –

相关问题