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

Auteur Sujet: [Résolu][SFML2.0]mutex.lock consécutifs, pas de blocage.  (Lu 8856 fois)

0 Membres et 1 Invité sur ce sujet

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
[Résolu][SFML2.0]mutex.lock consécutifs, pas de blocage.
« le: Juin 30, 2012, 07:21:44 pm »
Bonjour,

Je viens de m'apercevoir que plusieurs mutex.lock() consécutifs (testé avec 10 lock consécutifs) ne sont pas bloquants au niveau des lock() suivants le premier alors qu'ils devraient.

    sf::Mutex x;
    for(int i=0; i != 10; ++i)
        x.lock()

Ceci rend donc impossible le blocage d'un thread par lui-même pour être ensuite débloquer par un autre thread.


Dans le cas où les lock consécutifs seraient une erreur, le débogage devient un peu plus compliqué et certaines erreurs pourraient devenir très difficiles à trouver.

Est-ce une erreur ou est-ce voulu?
« Modifié: Juillet 03, 2012, 02:16:12 pm par Neckara »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #1 le: Juin 30, 2012, 08:11:19 pm »
Oui :

Citation de: la doc
SFML mutexes are recursive, which means that you can lock a mutex multiple times in the same thread without creating a deadlock

Verrouiller un thread plusieurs fois dans le même thread n'a aucun sens (sauf cas très particulier). Je ne sais pas ce que tu voulais faire, mais tu n'es pas dans la bonne direction.
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #2 le: Juillet 01, 2012, 11:42:05 am »
Disons que j'ai une fonction qui fait un mutex.lock qui appelait une fonction qui elle-même appelait une fonction qui faisait aussi un mutex.lock.

Or comme je n'avais pas de deadlock, trouver l'erreur a été beaucoup plus compliqué.
Sachant que l'erreur pouvait ne pas se manifester à chaque coup...

Sinon pour tes cas très particulier, il y a la réunion :

//thread 1
m.lock();
while(1)
{

         n.unlock();
         m.lock(); //attente du thread 2
}

//thread2
n.lock();
while(1)
{

       m.unlock();
       n.lock(); //attente du thread1
}
 

blocage d'un thread :
m.lock();
while(running)
{
       //construction d'un élément quelconque
       while(running && ! bloque)
       {
                //utilisation de l'élément
        }
        //destruction de l'objet
        if(bloque)
                m.lock();
}

//thread2
bloque = true; //blocage
//.....
bloque = false;
m.unlock(); //déblocage
 

Je ne vois pas l'intérêt de ne pas bloquer lors de lock consécutifs.
Si les lock consécutifs sont dû à une erreur, alors on ne résout pas l'erreur, on ne fait que la cacher.
C'est un peu comme un :
try
{

}
catch(..)
{
       //erreur ;-)
}
On empêche juste l'application de planter sur le coup mais rien ne l'empêche de planter plus tard justement à cause de cette erreur.
« Modifié: Juillet 01, 2012, 03:14:35 pm par Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #3 le: Juillet 01, 2012, 03:21:26 pm »
Hum... normalement les paires lock/unlock doivent être faites dans le même thread, je ne pense pas qu'un mutex puisse être déverrouillé depuis un autre thread, ça ne marche pas comme ça.
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #4 le: Juillet 01, 2012, 03:57:41 pm »
Un mutex n'est-il pas sensé se baser sur une instruction assembleur TSL ?

Ainsi on lit la valeur contenue dans un registre particulier puis on la remplie d'une valeur aléatoire (!= 0) et ce de manière atomique.

Si la valeur reçu est 0, on entre dans la section critique sinon on rajoute le thread à une liste.

Lors du unlock(), on regarde la liste, si elle est vide, on écrit 0 dans le registre sinon on réveille l'un des thread.


Je ne comprend donc pas pourquoi on ne pourrait pas faire un unlock() sur un thread différent de celui qui a fait le lock.

Ne vaut-il pas mieux d'utiliser des mutex rapides : PTHREAD_MUTEX_INITIALIZER
au lieu de mutex récursifs : PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP

Et d'implémenter une méthode tryLock() qui appellerait la fonction pthread_mutex_trylock ?
(et TryEnterCriticalSection pour windows)

Car tous les ordinateurs ne supporteraient pas les mutex récursifs d'après mes recherches.

Au pire on pourrait utiliser des mutex avec vérifications d'erreurs : PTHREAD_ERREURCHECK_MUTEX_INITIALIZER_NP .
« Modifié: Juillet 01, 2012, 04:42:19 pm par Neckara »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #5 le: Juillet 01, 2012, 06:28:37 pm »
Citer
Un mutex n'est-il pas sensé se baser sur une instruction assembleur TSL ?
Le "mutex" est surtout un concept, après il y a différentes formes de mutex, avec différentes implémentations sur différentes plateformes. On n'a pas besoin de connaître les détails, on peut s'en tenir à la définition fonctionnelle et technique du mutex.

Citer
Je ne comprend donc pas pourquoi on ne pourrait pas faire un unlock() sur un thread différent de celui qui a fait le lock.
Parce que c'est comme ça que fonctionnent les mutexs. Après une recherche rapide c'est inscrit dans la page de manuel de pthread. Je te laisse chercher un peu si tu veux trouver d'autres sources de confirmation ; j'ai pas vraiment le temps de le faire là :)

Citer
Ne vaut-il pas mieux d'utiliser des mutex rapides : PTHREAD_MUTEX_INITIALIZER
au lieu de mutex récursifs : PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP

Et d'implémenter une méthode tryLock() qui appellerait la fonction pthread_mutex_trylock ?
Ca pourrait éventuellement être possible par rapport à la raison pour laquelle j'ai mis les mutexs en mode récursif par défaut. Et encore, ça dépend du comportement de tryLock lorsque le mutex a été verrouillé dans le même thread.
Mais... y a-t-il une bonne raison de le faire ? Personnellement je ne le pense pas.
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #6 le: Juillet 01, 2012, 09:40:50 pm »
pthread_mutex_trylock rend la main immédiatement avec le code d'erreur EBUSY si le mutex a été verrouillé dans le thread (ou ailleurs).

Ceci permet donc de repérer les erreurs plus facilement.

Donc sinon il va falloir que j'utilise des sémaphores pour rendre un jeton sur un autre thread que celui qui a pris un jeton, ainsi que pour bloquer un thread.
« Modifié: Juillet 01, 2012, 09:44:56 pm par Neckara »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #7 le: Juillet 01, 2012, 09:46:44 pm »
Concrètement, tu veux implémenter quel algorithme ?
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #8 le: Juillet 01, 2012, 11:05:48 pm »
J'ai un thread qui se charge de la réception de paquet :

//thread producteur.

//création des threads consommateurs
while(running)
{
          //je construit un TcpListener et un SocketSelector
          while(running && ! bloque)
          {
                     //reception d'un paquet
                     //si nécessaire ajoute le paquet à une file de paquet. Le paquet sera alors traité par un ensemble de thread consommateurs.
           }
           //destruction du TcpListener et tu SocketSelector
           if(bloque)
                      //on bloque le thread jusqu'à ce qu'on décide de rouvrir le serveur aux clients
}
//destruction des threads consommateurs
 

Ainsi si le serveur reçoit plusieurs instructions (reçu par un autre thread avec un listener qui écoute sur un autre port) selon lesquelles il doit bloquer (ou débloquer) le thread producteur, on peut les traiter sans se soucier de l'état du thread producteur.
« Modifié: Juillet 02, 2012, 08:27:46 am par Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #9 le: Juillet 02, 2012, 08:52:44 am »
Si tu veux réveiller un thread depuis un autre, c'est une toute autre primitive qu'il faut utiliser, à savoir les "wait condition" (pthread_cond_t dans pthread). Tu peux les trouver un peu partout... sauf dans SFML ;D
Laurent Gomila - SFML developer

Ceylo

  • Hero Member
  • *****
  • Messages: 2325
    • Voir le profil
    • http://sfemovie.yalir.org/
    • E-mail
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #10 le: Juillet 02, 2012, 11:58:40 am »
Tu peux regarder Condition.hpp si tu veux une implémentation un peu bizarre de condition. Mais dans tous les cas ça peut au moins te servir de base.
Want to play movies in your SFML application? Check out sfeMovie!

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #11 le: Juillet 03, 2012, 09:08:22 am »
Merci pour vos réponses.

Comme je vais devoir implémenter les wait condition et plus tard les threads pour windows et les unix, est-ce que vous voudriez que je vous donne les sources pour éventuellement les rajouter à la SFML (ou servir de base pour un ajout futur) ?
Dans ce cas là je dois forker le dépôt github et soumettre une "pull request" ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #12 le: Juillet 03, 2012, 09:52:05 am »
Il n'y aura rien de cela dans SFML, étant donné que c'est déjà disponible dans le nouveau standard C++. Et dans boost. Et dans plein d'autres bibliothèques qui font ça bien mieux que moi.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : [SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #13 le: Juillet 03, 2012, 10:05:00 am »
Oui et rien ne t'empêche d'utiliser plusieurs bibliothèques. ;)
Moi pour mon projet j'utilise boost, la sfml et QT.  ;D
C'est tout simplement génial!

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [Résolu][SFML2.0]mutex.lock consécutifs, pas de blocage.
« Réponse #14 le: Juillet 03, 2012, 02:16:32 pm »
D'accord, merci pour vos réponses.