微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 std::async 调用的方法行为不正确

如何解决使用 std::async 调用的方法行为不正确

我有一个方法可以启动我的程序状态并加快整个过程,我正在尝试向我的应用程序添加多线程(第一次使用它 - 仍在学习)。问题是,当我正常调用它时一切都很好,但是使用 std::future 和 std::async 我遇到了一些问题 (比如复制SFML纹理时的gl_invalid_operation或者有时wstring中的某些字母不正确)。

我以前从未接触过多线程,但根据许多教程,一切都应该没问题。

我的代码

Settingsstate.cpp

void Settingsstate::InitState()
{

#define ASYNC 1
#if ASYNC

    // Weird behavior
    std::future<void> gen_gui_init =  std::async(std::launch::async,&Settingsstate::InitGenSetGUI,this);
    std::future<void> win_sett_init = std::async(std::launch::async,&Settingsstate::InitwindowSettings,this);
    std::future<void> aud_sett_init = std::async(std::launch::async,&Settingsstate::InitAudioSettings,this);
    std::future<void> sim_sett_init = std::async(std::launch::async,&Settingsstate::InitSimulationSettings,this);
    std::future<void> key_sett_init = std::async(std::launch::async,&Settingsstate::InitKeybindsSettings,this);

#else

    // Everything is fine
    this->InitGenSetGUI();
    this->InitwindowSettings();
    this->InitAudioSettings();
    this->InitSimulationSettings();
    this->InitKeybindsSettings();

#endif

}

Settingsstate.hpp

class Settingsstate :
    public State
{
public:
    // constructors

    void InitState();

    void InitGenSetGUI();
    void InitwindowSettings();
    void InitAudioSettings();
    void InitSimulationSettings();
    void InitKeybindsSettings();

    // other methods and members
};

我认为 std::future 有问题,但正如我所说,我刚刚接触它并找不到答案。提前致谢

其他初始化:

void Settingsstate::InitGenSetGUI()
{
    const int types_number = 4;
    //const int wSettingsColorsCount = 26;

    sf::Event fake_event;

    m_stateBackground.create(winSize,{ 0,0 },ke::Origin::LEFT_TOP,"Textures/earth_view2.png");
    m_backgroundMask.create(winSize,L"",{},sf::Color(0,255.f - 255.f * AppSettings::BackgroundBrightness() * 0.01f));
    m_stateMask.create(winSize,0));


    // SETTINGS GUI


    // window settings types

    m_settings_types.reserve(types_number);

    m_settings_types.emplace_back(std::make_unique<ke::Rectangle>(winSize / 9.f,sf::Vector2f(1 * winSize.x / 9,winSize.y / 18),L"Window",winSize.y / 32.f,ke::Origin::MIDDLE_MIDDLE,sf::Color::Transparent,sf::Color(255,255,255)));
    m_settings_types.emplace_back(std::make_unique<ke::Rectangle>(winSize / 9.f,sf::Vector2f(3 * winSize.x / 9,L"Audio",128)));
    m_settings_types.emplace_back(std::make_unique<ke::Rectangle>(winSize / 9.f,sf::Vector2f(5 * winSize.x / 9,L"Simulation",sf::Vector2f(7 * winSize.x / 9,L"Keybinds",128)));

    m_selected_type_itr = m_settings_types.begin();

    for (auto& itr : m_settings_types)
        itr->update({ 0,fake_event,sf::Mouse::Left,nullptr);


    // separation bar

    m_separation_bar.create({ winSize.x,winSize.y / 576 },winSize.y / 4.5f },ke::Origin::LEFT_MIDDLE,160));


    // slider

    m_slider.create({ winSize.x / 100,winSize.y - winSize.y / 4.5f },{ winSize.x,viewSize.y * 1.1f,ke::Origin::RIGHT_TOP,nullptr,sf::Color(192,192,128),sf::Color(128,128,128));


    // apply and restore defaults button

    m_apply_button.create({ winSize.x * 0.1f,winSize.y * 0.05f },{ winSize.x / 6.f,0.95f * winSize.y },ke::RIGHT_TOP,L"Apply",64),192));
    m_restore_def_buttoon.create({ winSize.x * 0.1f,ke::LEFT_TOP,L"Restore defaults",winSize.y / 48.f,255));
}




////////////////////////////////////////////////////////////////



void Settingsstate::InitwindowSettings()
{
    // WINDOW SETTINGS

    sf::Event fake_event;
    auto color_itr = m_windowSettings_colors.begin();


    // FPS bars

    m_maxMenuFPS_bar.create({ winSize.x / 6,winSize.y / 24 },{ 0.6f * winSize.x,4 * winSize.y * 0.1f },AppSettings::MaxMenuFPS(),30,240,sf::Color::Black,160),winSize.y / 450,sf::Color::Transparent);;
    m_maxSimfpS_bar.create({ winSize.x / 6,5 * winSize.y * 0.1f },AppSettings::MaxSimulationFPS(),120,960,sf::Color::Transparent);;


    // FPS bars accessories

    m_WS_accessories.reserve(11);

    m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.y / 24.f,winSize.y / 24.f),sf::Vector2f(0.6f * winSize.x,4 * winSize.y * 0.1f),ke::Origin::RIGHT_MIDDLE,"Textures/left_arrow2.png"));
    m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.y / 24.f,sf::Vector2f(23.f * winSize.x / 30,"Textures/right_arrow2.png"));
    m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.x / 6.f,sf::Vector2f(0.4f * winSize.x,L"Menu FPS limit",winSize.y / 32,160)));
    m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.y / 24.f,std::to_wstring(AppSettings::MaxMenuFPS()),winSize.y / 48,sf::Text::Regular,sf::Vector2f(2 * winSize.y / 450,0)));

    m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.y / 24.f,5 * winSize.y * 0.1f),L"Simulation FPS limit",std::to_wstring(AppSettings::MaxSimulationFPS()),0)));

    if (m_maxSimfpS_bar.getPointCount() >= 960)
        m_WS_accessories.at(7)->setText(L"Unlimited");

    // vertical sync status buttons

    m_vSyncOn.create({ winSize.x / 12.f,winSize.y / 24.f },{ 41.f * winSize.x / 60.f,6.f * winSize.y * 0.1f },L"ON",sf::Color(160,160,sf::Color::Black);
    m_vSyncOff.create({ winSize.x / 12.f,L"OFF",sf::Color::Black);

    if (m_vSyncStatus)
    {
        m_vSyncOn.setFillColor(sf::Color(255,192));
        m_vSyncOn.setTextStyle(sf::Text::Bold);
    }
    else
    {
        m_vSyncOff.setFillColor(sf::Color(255,192));
        m_vSyncOff.setTextStyle(sf::Text::Bold);
    }


    // vertical sync buttons accessories

    m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.x / 6,winSize.y / 24),6 * winSize.y * 0.1f),L"Vertical Synchronization",160)));



    // bright level bar

    m_bright_lvl.create({ winSize.x / 6.f,winSize.y / 49,7.f * winSize.y * 0.1f },255),sf::Color(96,96,255));
    m_bright_lvl.setPercent(AppSettings::BackgroundBrightness());


    // bright level accessories 

    m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.x / 6,7 * winSize.y * 0.1f),L"Background brightness",160)));



    // window size dropdown list

    m_windowSize_drl.create({ winSize.x / 6.f,8.f * winSize.y * 0.1f },"Textures/earth_view2.png",L"Something went wrong :(",192),sf::Text::Bold);
    m_windowSize_drl.addMember(nullptr,L"1024 \u00D7 576",winSize.y / 56,255));
    m_windowSize_drl.addMember(nullptr,L"1280 \u00D7 720",L"1366 \u00D7 768",L"1600 \u00D7 900",L"1920 \u00D7 1080",L"1920 \u00D7 1080 Fullscreen",255));

    for (auto& itr : *m_windowSize_drl.getMembers())
        itr->update({ 0,nullptr);


    if (AppSettings::DefaultwindowSize() == sf::Vector2f(1024,576)) m_windowSize_drl.setMemberAsActive(0);
    if (AppSettings::DefaultwindowSize() == sf::Vector2f(1280,720)) m_windowSize_drl.setMemberAsActive(1);
    if (AppSettings::DefaultwindowSize() == sf::Vector2f(1366,768)) m_windowSize_drl.setMemberAsActive(2);
    if (AppSettings::DefaultwindowSize() == sf::Vector2f(1600,900)) m_windowSize_drl.setMemberAsActive(3);
    if (AppSettings::DefaultwindowSize() == sf::Vector2f(1920,1080)) m_windowSize_drl.setMemberAsActive(4);
    if (AppSettings::DefaultwindowSize() == sf::Vector2f(1920,1080)) m_windowSize_drl.setMemberAsActive(5);


    m_start_window_size = m_windowSize_drl.getSelectedID();
    m_current_window_size = m_windowSize_drl.getSelectedID();


    // window size dropdown list accessories

    m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.x / 6,8 * winSize.y * 0.1f),L"Window Resolution",160)));
}

解决方法

在使用它之前,您需要在线程中初始化 OpenGL。更多信息在这里: https://www.khronos.org/opengl/wiki/OpenGL_and_multithreading

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。