71 votes

Programme multithread bloqué en mode optimisé mais s'exécute normalement en -O0

J'ai écrit un simple programme multithread comme suit :

 static bool finished = false;

int func()
{
    size_t i = 0;
    while (!finished)
        ++i;
    return i;
}

int main()
{
    auto result=std::async(std::launch::async, func);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    finished=true;
    std::cout<<"result ="<<result.get();
    std::cout<<"\nmain thread id="<<std::this_thread::get_id()<<std::endl;
}

Il se comporte normalement en mode débogage dans Visual studio ou -O0 dans gc c et imprime le résultat après 1 secondes. Mais il s'est bloqué et n'imprime rien en mode Release -O1 -O2 -O3 .

5voto

Oblivion Points 6320

Par souci d'exhaustivité dans la courbe d'apprentissage; vous devriez éviter d'utiliser des variables globales. Vous avez fait du bon travail en le rendant statique, il sera donc local pour l'unité de traduction.

Voici un exemple:

 class ST {
public:
    int func()
    {
        size_t i = 0;
        while (!finished)
            ++i;
        return i;
    }
    void setFinished(bool val)
    {
        finished = val;
    }
private:
    std::atomic<bool> finished = false;
};

int main()
{
    ST st;
    auto result=std::async(std::launch::async, &ST::func, std::ref(st));
    std::this_thread::sleep_for(std::chrono::seconds(1));
    st.setFinished(true);
    std::cout<<"result ="<<result.get();
    std::cout<<"\nmain thread id="<<std::this_thread::get_id()<<std::endl;
}

En direct sur la boîte à baguettes

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X