Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Comment bien utiliser les mutex ?  (Lu 40302 fois)

0 Membres et 1 Invité sur ce sujet

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Note que SFML possède un binding Java, si tu préfères cet environnement.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Je ne tiens pas à recoder, plus de 50 fichiers en c++, en java. :/ (Mon jeux va encore contenir plus de fichier que ta bibliothéque vu qu'il y a mon propre framework qui englobe la SFML + le gameplay, et , quelques fichier SFML que j'ai modifié.)

Tu utilises JOGL pour le binding java ?

Je n'aime pas trop JOGL, elle utilise un thread en interne pour gérer l'affihage et ça m'a posé des problèmes d'accès concurrant avec d'autres composants java comme par exemple, les arraylist.

De plus je ne sais pas très bien comment fonctionne le système de gestion des accès concurrants en java avec wait() et notify() pour ça que je suis passé à la SFML avec les mutex qui sont largement plus simple à utilisé.

Maintenant si tu n'utilises pas JOGL j'aurai surement utilisé le binding java mais il n'existait pas encore je pense au moment ou j'ai commencé à passé au c++. (Celà fait maintenant déja depuis pas mal d'années.)
« Modifié: Août 10, 2013, 05:33:23 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Citer
Tu utilises JOGL pour le binding java ?
Déjà ce n'est pas moi qui l'ai écrit. Ensuite non, c'est un binding donc tout ce qu'il utilise c'est SFML (C++). Un binding n'est pas une réécriture, c'est un wrapper par dessus la bibliothèque originale.

Citer
De plus je ne sais pas très bien comment fonctionne le système de gestion des accès concurrants en java avec wait() et notify() pour ça que je suis passé à la SFML avec les mutex qui sont largement plus simple à utilisé.
wait() + notify(), c'est le mécanisme qu'on nomme en général "condition" ou "variable de condition". C'est très différent des mutexs (complémentaire), et c'est intéressant / utile de savoir un peu ce que c'est et comment ça fonctionne. Même en C++ c'est très souvent utile.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Un warper, ok, alors il passe surement par un mécanisme qui permet d'insérer du code écrit en c++ dans du code java, je ne sais plus comment ça s'appelle. (Mais oui c'est vrai qu'il y a moyen.)
Bref je pourrai toujours apprendre à me servir des variables de condition, avec les thread du c++11 surement, avant de faire un binding java de mon framework.
Mais je suis pas un spécialiste je ne sais pas du tout quand c'est mieux d'utiliser les variables de condition, quand c'est mieux d'utiliser les mutex ou autre chose.

Mais java utilise bien des variables de condition.
« Modifié: Août 10, 2013, 08:34:47 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Citer
Un warper, ok, alors il passe surement par un mécanisme qui permet d'insérer du code écrit en c++ dans du code java, je ne sais plus comment ça s'appelle.
JNI.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Bien que pour la 2D en java j'aurai peut être pas eu besoin de passer par la SFML, ça inclus déjà toute les classes 2D dont j'ai besoin.

J'ai regardé un article sur les thread en plus, il y a pas mal de trucs bien pour la syncchronisation :
Il y a aussi les mutex mais en plus les sémaphore, les variables de conditions, un Executor, etc...
Qui pourraient être intéressant si je décide un jour de passer en multithreading, et que je n'ai pas vraiment le choix au niveau de l'implémentation pour les accès concurrents mais bon pas encore sûr que j'aurai besoin d'autre primitives de synchronisation que les mutex, je vais essayer de faire un système de liste d'attente plutôt si un jour je décide de passé en multi-threading. (un thread pour update la liste de tiles et un autre thread pour les afficher.)
Je pensais faire une classe SceneUpdater avec un thread, et un genre de vector a 2 dimensions contenant les tiles à afficher et la position dans la file d'attente. (Je peux pas utiliser une std::map vu que ça ne stocke pas les informations dans l'ordre dans lequel on les insères, donc là c'est encore plus compliqué je suis obligé de faire un vector qui sotcke les ordres d'insertion, bref...)
Je trouverais bien un truc pour ma passer de toute ces complications inutiles. :)
Par contre y'a un endroit ou je sais pas faire sans mutex et ça m'embête un peut, c'est que, l'utilisateur changer de chemin, on ne peut pas changer chemin en même temps que l'autre thread update la position du personnage à partir de l'ancien chemin.
Et je pense que c'est là que ça freeze un peu.
Pas vraiment trouvé de manière de contourné un mutex pour ce là. :/

Et c'est là que ça freeze un peu. :/
« Modifié: Août 10, 2013, 10:15:46 pm par Lolilolight »

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Et puis on est jamais à l'abris des accès concurrents car même si on gère une liste d'attente, les thread pourront accèder à cette liste d'attente en même temps donc..., ça ne résoudrait pas le problème.

Je ne vois rien d'autre que d'utiliser autre chose qu'un mutex dans ce cas là, comme par exemple, la classe Executor en java qui exécute les actions dans l'ordre dans lequel elle sont ajoutée, et qui je pense est beaucoup plus optimisé qu'un mutex.

Le c++11 possède peut être un truc du genre, faudrait que je prenne le temps d'y jeter un coup d'oeuil, sinon, je repasserai surement au java.
Bref en gros ce style de code pour réduire les accès concurrent c'est pas à haut niveau que ça doit se faire,donc, pas dans mon code, c'est à plus bas niveau que ça se fait.
« Modifié: Août 10, 2013, 10:37:21 pm par Lolilolight »

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Thread et mutex, comment bien les utiliser ?
« Réponse #82 le: Août 11, 2013, 07:49:14 am »
Bon pour la seconde solution j'ai trouvé, plutôt que de verouiller le mutex à chaque tour de boucle, je vais faire ceci :

-Le personnage veut bouger : il vérifie si un déplacement est en cours, si oui, il demande à l'autre thread de verouiller le mutex  et attend que le mutex soit verrouillé avant de changer sa trajectoire, puis il demande à l'autre thread de déverouillé le mutex.

Par contre je vois pas trop comment faire un système multi-thread qui mets à jour et affiche les tiles, je voudrais faire en fait comme le fait Swing en java, en utilisant une liste blocante, voici le tutoriel en question qui explique à quoi ça ressemble (voir la fin ou il parle de l'exécutor.) : http://rom.developpez.com/java-synchronisation/

Mais là je vois pas encore trop bien comment implémenter ça.  :-\

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Bon ça va j'ai enfin trouvé mon bonheur : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3562.pdf

Donc go pour le c++11 qui me permettra de faire du code plus optimisé. :)

J'ai lu pas mal d'article et ça a l'air bien le c++11. :)

Bref le problème vient du fait que les thread de la sfml et les mutex ne sont plus suffisant pour ce que je veux faire si je veux passer en multi-thread. :/
Donc on peut dire que ce sujet est résolu. :)
« Modifié: Août 11, 2013, 08:24:45 am par Lolilolight »

cobra.one

  • Newbie
  • *
  • Messages: 26
    • Voir le profil
Re : Comment bien utiliser les mutex ?
« Réponse #84 le: Août 11, 2013, 12:15:26 pm »
Mais la question c'est : as-tu réellement besoin de gérer tout un bric à brac de threads qui risque de tout compliquer sans te rendre réellement service par rapport à un système mono thread ?

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Comment bien utiliser les mutex ?
« Réponse #85 le: Août 11, 2013, 12:31:47 pm »
Citer
Mais la question c'est : as-tu réellement besoin de gérer tout un bric à brac de threads qui risque de tout compliquer sans te rendre réellement service par rapport à un système mono thread ?

Heu peut être que j'en ai pas besoin mais se serait dommage de s'en passer sur un PC multi-coeur.

J'ai essayer d'utiliser une variable de condition avec les thread du c++11 pour verrouiller le mutex que quand le personnage change de trajectoire uniquement et donc pour verouiller seulement quand cela est nacessaire :

unique_lock<mutex> locker(server.getGLockModifyPath());
    //avoid spurious wakeup.
    while(!server.isGNotified()) {
        g_signal.wait(locker);
    }
Mise à jour de la position du personnage suivant sa trajectoire.
 
Changement de trajectoire.
               unique_lock<mutex> locker (server.getLockModifyPath());
               server.setGNotified(false);
               (*it).first->getCurrentCar()->setFightingMode(false);
               (*it).first->getCurrentCar()->setAttacking(false);
               (*it).first->getCurrentCar()->setFocusedMonster(NULL);
               vector<string> parts = split(message, "#");
               GridMap &gm = *World::getMap("Map test")->gridMap;
               Vec2f startPos (conversionStringInt(parts[0]), conversionStringInt(parts[1]));
               Vec2f finalPos (conversionStringInt(parts[2]), conversionStringInt(parts[3]));

               vector<Vec2f> positions = gm.getPath(startPos, finalPos);
               Caracter *car = (*it).first->getCurrentCar();
               car->setPath(positions);
               car->setCurrentPointIndex(0);
               Vec2f dir = (car->getPath()[1] - car->getCenter()).normalize();
               car->setDir(dir);
               car->setMoveFromKeyboard(false);
               car->setMoving(true);
               vector<Vec2f> path = car->getPath();
               response = "PPATH*"+conversionIntString(path.size())+"*";
               for (unsigned int i = 0; i < path.size(); i++) {
                    response += conversionIntString(path[i].x)+"*"+conversionIntString(path[i].y);
                    if (i != path.size() - 1)
                        response += "*";
               }
               packet<<response;
               (*it).first->sendTCPMessage(packet);
               server.setGNotified(true);
               //Fait appel à g_signal.notify_one()
               server.notify();
 
Mais ça ne résoud pas le problème, le problème vient parfois en plein milieu du déplacement et pas toujours quand je change de trajectoire donc, c'est quand je déplace ma vue côté client que ça bloque quelque part, et pas côté serveur, j'ai aussi se problème en monothread avec mon éditeur de map, déplacement de la vue lente parfois...

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Ca tourne!!!
« Réponse #86 le: Août 11, 2013, 01:55:45 pm »
Ca y est, ça tourne enfin!

En fait j'ai déclarer mon mutex en statique et je l'ai passé à mes classes plutôt que de faire un getter renvoyant une référence sur le mutex, car, apparemment faire comme ça c'est archi lent!

Bref merci au c++11, c'est tout simplement de la balle.  :)

« Modifié: Août 11, 2013, 02:05:04 pm par Lolilolight »

cobra.one

  • Newbie
  • *
  • Messages: 26
    • Voir le profil
Re : Re : Comment bien utiliser les mutex ?
« Réponse #87 le: Août 11, 2013, 02:06:41 pm »
Citer
Mais la question c'est : as-tu réellement besoin de gérer tout un bric à brac de threads qui risque de tout compliquer sans te rendre réellement service par rapport à un système mono thread ?

Heu peut être que j'en ai pas besoin mais se serait dommage de s'en passer sur un PC multi-coeur.

Hélas il ne suffit pas de créer quelques threads ça et là et de laisser le système se débrouiller avec pour que ça soit plus efficace qu'un seul thread qui réaliserait les mêmes opérations.
« Modifié: Août 11, 2013, 02:37:34 pm par cobra.one »

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Comment bien utiliser les mutex ?
« Réponse #88 le: Août 11, 2013, 03:05:27 pm »
En effet bref heureusement que y'a le c++11 et d'autres librairies qui introduisent des primitives de synchronisation de plus haut niveau que le mutex qui permettent de gérer une liste d'attente sinon j'aurai galéré en effet. :/

Mais pour l'affichage et la mise à jour des tiles je pense que je vais laisser ça dans un seul thread vu que je galère déja assez comme ça. :/
« Modifié: Août 11, 2013, 03:07:18 pm par Lolilolight »

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Comment bien utiliser les mutex ?
« Réponse #89 le: Août 11, 2013, 04:18:36 pm »
Bien que à la limite je pourrai peut être maintenant, grâce à cet exemple de code source fournis par cet excellent lien : http://www.codeproject.com/Articles/598695/Cplusplus11-threads-locks-and-condition-variables
La sfml ne suffirait pas pour faire ce genre de chose. (J'ai en effet un écran noir quand mon thread n'a pas fini d'ajouter les tiles visibles à l'écran dans le vecteur quand je déplace la vue du coup résultat incohérent et mon écran se met à clignoter.)
Il me faut donc utiliser une variable de condition, qui exécute le code d'affichage que si le vecteur de tiles est rempli.

C'est le même principe que le code source plus bas ou il a 2 thread, un qui ajoute les message d'erreur dans un vecteur et l'autre thread qui les affiche à l'écran.

Je pense que en adaptant mon code pour qu'il fasse la même chose avec mes tiles, (il me faudra juste un vecteur a 2 dimensions car j'affiche plusieurs tiles d'un coup et pas un message à la fois comme dans son exemple.) il doit y avoir moyen de faire ne sorte que ça soit plus éfficace qu'avec un seul thread.