IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Threads & Processus C++ Discussion :

Utiliser / Ecriture sur une variable pour plusieurs Threads ?


Sujet :

Threads & Processus C++

  1. #1
    Membre régulier
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2015
    Messages : 10
    Par défaut Utiliser / Ecriture sur une variable pour plusieurs Threads ?
    Bonjours (ou bonsoir ?) à tous, je suis vraiment (mais alors mais très) nouveau sur le multithreading et en essayant une chose qui est d'utiliser un Thread pour écrire dans une variable en continue et le Thread du main pour lire cette même variable, j'ai un problème qui est que la variable ne change pas de valeur dans le main mais pourtant elle change dans le 1er Thread, alors je me demandais si il y avait une solution pour utiliser la même variable sur deux Threads.

    Je vous remercies d'avance pour vos réponse (et s'il vous plaît, c'est la première fois que je touche au multithreading alors soyez indulgents svp ^^)

  2. #2
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Ta variable est une ressource partagée dont il faut encadrer l'accès par une primitive d'exclusion mutuelle, tu ne peux pas y lire et y écrire comme d'habitude, freestyle. D'autre part ta configuration semble correspondre à un problème de producteur-consommateur pour lequel il existe diverses solutions. Pourrais-tu nous donner plus de détails ?

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 146
    Billets dans le blog
    4
    Par défaut
    Un peu de code aiderait à y voir plus clair.
    Dans le main tu as une valeur copiée depuis ta variable, peut-être tout simplement parce que tu la copies, peut-être parce que le compilateur la copie pour toi pensant à une optimisation.
    Utiliser des std::atomic de la bonne manière permettrait d'éviter ça dans un premier temps, comprendre comment fonctionne thread et mutex feront aller plus loin.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Membre régulier
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2015
    Messages : 10
    Par défaut
    Merci pour vos réponses rapides, pour le bout de code voici la partie pour laquelle je pose la question:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    int my_thread(void *data)
                  {
                       VariableClasse vc;
                       int a;
     
                       while (continuer) //Variable à part
                       {
                            a++;
                            vc.setVariable(a);
                       }
     
                  }
    int main()
                  {
                       SDL_Thread *thread;
                       thread = SDL_CreateThread(my_thread, MainScreen); //Démarre le Thread 
                       VariableClasse vc;
                       int a;
                       while (continuer)
                       {                
                            a = vc.getVariable(); //Cette variable est la même que celle qui est "set"
                       }
                   }
    Et après pour voir l'état des deux variables, j'ai décidé de mettre un ofstream dans le Thread du haut qui pas dans un fichier texte et ça fonctionne bien pour lui, par contre pour celui du main je le fais aller dans un autre fichier texte mais la variable ne change jamais.

  5. #5
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Mouais.. ce n'est pas très clair tout ça. Tu n'aurais pas un exemple minimal réel (qui compile) pour voir ?

    En l'état tu as deux variables vc différentes puisqu'il y a une déclaration dans chaque thread. Se pourrait-il que tu aies aussi cela dans ton programme ? Auquel cas rien d'étonnant à ce que la variable du main thread reste inchangée : c'en est une autre. Tu dois transmettre au worker thread des références aux ressources partagées via ses arguments (void *data).

    Ensuite, il reste encore à encadrer les accès à ces ressources (get, set) par des verrous. Je ne sais pas quelles sont les primitives disponibles avec SDL.

  6. #6
    Membre régulier
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2015
    Messages : 10
    Par défaut
    Pour l'exemple minimal, celui =-ci devrai compiler (je dis bien devrai car depuis peu, me projets SDL finissent tous avec des status comme -1073741510 etc...)

    Main.cpp:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #include <SDL/SDL.h>
    #include <SDL/SDL_thread.h>
    #include "Ennemis.h"
    #include <fstream>
    using namespace std;
     
    SDL_Thread *thread;
     
    int continuer;
     
    int my_thread(void *Data)
    {
        int positionX = 1000;
        int positionXJoueur = 0;
        Ennemis e;
        ofstream fichier("testThread.txt", ios::out | ios::trunc); //Utilisation de ofstream car la console n'affiche rien ni pendant le débogage ni après
        while (continuer)
        {
     
            while (positionX > positionXJoueur + 50) //PositionX est celle du bot
            {
                positionX-=2;
                e.setPositionX(positionX);
                fichier << positionX << endl;
     
            }
     
        }
        fichier.close();
    }
     
    int main ( int argc, char** argv )
    {
     
        SDL_Surface *ecran = NULL;
        SDL_Event event;
        SDL_Init(SDL_INIT_VIDEO);
     
        ecran = SDL_SetVideoMode(1000, 500, 8, SDL_DOUBLEBUF | SDL_HWSURFACE);
     
        Ennemis e;
        int positionX = 1000;
     
        ofstream fichier("testMain.txt", ios::out | ios::trunc);
     
        thread = SDL_CreateThread(my_thread, NULL);
        while (continuer)
        {
     
            SDL_WaitEvent(&event);
            switch (event.type)
            {
                case SDL_QUIT:
                    continuer = 0;
                    break;
            }
            positionX = e.getPositionX();
            fichier << positionX << endl;
        }
        fichier.close();
    }
    Ennemis.h:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <SDL/SDL.h>
     
    class Ennemis
    {
        public:
            Ennemis();
            void setPositionX(int X);
            int getPositionX();
     
        private:
            int positionXG; //Position X Accessible par tous avec les fonctions Set et Get
     
    };
    Ennemis.cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include "Ennemis.h"
     
    int Ennemis::getPositionX()
    {
        return Ennemis::positionXG;
    }
     
    void Ennemis::setPositionX(int X)
    {
        Ennemis::positionXG = X;
    }
     
    Ennemis::Ennemis()
    {
        Ennemis::positionXG = 1000;
    }
    Et il existe juste des Mutex à initialiser et utiliser dans les fonction SDL_MutexP(SDL_Mutex *mutex) pour ouvrir le mutex et SDL_MutexV(SDL_Mutex *mutex) pour le fermer.

  7. #7
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Tu obtiens des valeurs de retour imprévisibles car ton main ne renvoie rien, ajoute un return explicite.

    Au sujet du programme en lui-même :

    • les deux threads exploitent effectivement des variables différentes et il n'y a pas de synchronisation, les remarques de mon précédent message s'appliquent donc ;
    • si tu ne join pas les threads en cours d'exécution avant la sortie du main proprement avec SDL_WaitThread, le système va les kill comme un bourrin.

    Attention, SDL_MutexP et V sont dépréciés au profit de SDL_LockMutex.


    Je me permets d'ajouter une chose : le multithreading c'est difficile. Vraiment, c'est chaud. C'est très bien de t'y intéresser mais ça ne s'improvise pas. Je te conseillerais d'écrire d'abord un programme séquentiel qui tourne et que tu maîtrises bien pour ensuite voir ce que tu peux paralléliser.

  8. #8
    Membre régulier
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2015
    Messages : 10
    Par défaut
    Bonjour me revoici, j'ai remplacer les mutexP et V pour des SDL_LockMutex et SDL_UnlockMutex, j'ai aussi essayer d'utiliser le void *data avec des int mais succès (je crois que je n'ai pas bien compris les tutos sur internet) et du coup j'en suis toujours au même point ^^' j'avoues que tu as raison sur le point que les Threads soient difficiles.

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 146
    Billets dans le blog
    4
    Par défaut
    Maintenant que mutex et thread font partie de la std, autant les utiliser.
    Pour le reste, disons que connaître ce qu'est une portée de variable serait un bon départ avant d'espérer faire du multithread
    Btw, avec une classe Ennemi ça ressemble furieusement à une tentative de jeu-vidéo, et vouloir threader les pnj c'est pas vraiment une bonne idée. C'est la boucle de gameplay qui doit se charger de ça.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  10. #10
    Membre régulier
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2015
    Messages : 10
    Par défaut
    Finallement j'ai décidé d'abandonner le multithread désolé ^^' mais je trouves ça encroe un peu trop difficile pour mon niveau je verrais plus tard pour m'y retrouver un peu plus merci quand même pour vos réponses

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. multithreading: ecriture sur une variable unique
    Par divide dans le forum Threads & Processus
    Réponses: 3
    Dernier message: 25/01/2014, 19h00
  2. [Toutes versions] Une Variable pour plusieurs requetes ?
    Par mikeactuaire dans le forum Access
    Réponses: 2
    Dernier message: 11/10/2011, 22h18
  3. Utiliser include sur une variable de la barre d'adresse
    Par Loïc B. dans le forum Langage
    Réponses: 3
    Dernier message: 28/12/2010, 12h20
  4. partage d'une variable entre plusieurs threads
    Par baedal dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 27/02/2008, 20h33
  5. [VBA-E] Conserver une variable pour plusieurs modules
    Par pilote301152 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 13/05/2006, 13h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo