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

Auteur Sujet: [SFML2] Besoin d'un petit conseil thread/list.erase  (Lu 9248 fois)

0 Membres et 1 Invité sur ce sujet

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
[SFML2] Besoin d'un petit conseil thread/list.erase
« le: Mai 14, 2012, 11:38:58 pm »
Bonjour à tous et à toutes :)

J'ai une variable qui est partagée entre plusieurs threads :
std::list<DataUser> m_clients[32][18];
 
Bon vous savez les problèmes que ça apporte si l'un est en lecture et qu'en même temps, un autre thread supprime une entrée de la list.

J'ai donc trouvé les deque qui, dans ce cas, font pointer l'itérateur qui pointe sur rien (à cause d'une suppression) sur la donnée précédente dans la liste.

Voilà, seulement, comment être alerté que l'itérateur a changé ainsi dans une boucle ? Est-ce que on peut simplement stocker l'itérateur précédent et le comparer à l'itérateur actuel ? Ainsi, si les deux itérateurs sont équivalent, ça veut dire qu'il y a eu une suppression et du coup, faut pas exécuter le code qui va suivre...

Merci de votre patience et bonne journée ! 8)
« Modifié: Mai 14, 2012, 11:57:53 pm par neo007 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #1 le: Mai 15, 2012, 08:12:30 am »
Citer
J'ai donc trouvé les deque qui, dans ce cas, font pointer l'itérateur qui pointe sur rien (à cause d'une suppression) sur la donnée précédente dans la liste.
Ouhla... je ne sais pas pourquoi ça réagit comme ça chez toi, mais ne base pas ton code sur ce comportement.

std::deque, std::list ou n'importe quel autre conteneur standard, n'est pas thread-safe. Si tu as des accès concurrents il faut les éliminer avec un mutex ou autre. C'est la seule façon correcte de gérer ce genre de situation.

Ce que tu voulais faire là c'est du bricolage ultra-bancal.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #2 le: Mai 15, 2012, 01:15:18 pm »
D'accord et est-ce que la SFML intègre des mutex qui permettent de faire un model multiple-reader/single writer ?

Voici un code avec les mutex normal pour ce genre de problème, mais ça semble vraiment bordélique...

thread_lecture1
{
    mutex_écriture.lock();   //Si on écrit, alors on attend
    mutex_écriture.unlock(); //Écriture fini, on peut lire
    mutex_lecture1.lock();   //Lecture1 en cours... on lock le mutex
    //Plein de code...
    mutex_lecture1.unlock(); //Lecture terminée, on débloque le mutex de lecture1
}
thread_lecture2
{
    mutex_écriture.lock();   //Si on écrit, alors on attend
    mutex_écriture.unlock(); //Écriture fini, on peut lire
    mutex_lecture2.lock();   //Lecture2 en cours... on lock le mutex
    //Plein de code...
    mutex_lecture2.unlock(); //Lecture terminée, on débloque le mutex de lecture1
}
thread_écriture
{
    mutex_écriture.lock();   //On veut écrire, on lock le mutex d'écriture
    mutex_lecture1.lock();   //On s'assure que lecture1 n'est pas en cours
    mutex_lecture1.unlock(); //On le débloque, car le but n'est pas de le bloquer
    mutex_lecture2.lock();   //On s'assure que lecture2 n'est pas en cours
    mutex_lecture2.unlock(); //On le débloque, car le but n'est pas de le bloquer
    //Plein de code...
    mutex_écriture.unlock(); //Écriture terminée, on débloque le mutex de d'écriture
}
 

Sans compter qu'il va falloir mettre tout ça à jour si un jour j'ajoute un nouveau lecteur...

Quelle serait la meilleure solution sans sortir du cadre de la SFML ? On m'a présenté par exemple boost::shared_mutex, mais je ne suis vraiment pas intéressé à utiliser une autre bibliothèque que la SFML dans ce projet.

Merci et bonne journée ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #3 le: Mai 15, 2012, 01:18:28 pm »
C'est quoi ce merdier ? ;D (nan, bon, j'ai compris ce que tu veux faire -- mais la manière dont tu le fais, c'est bizarre)

Utilise un seul mutex pour tout le monde. Ce ne sera pas le plus optimal que tu puisses faire, mais si tu as vraiment besoin de faire des choses poussées (ce qui n'est pas forcément le cas) alors de toute façon SFML est insuffisante.
« Modifié: Mai 15, 2012, 01:21:20 pm par Laurent »
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #4 le: Mai 15, 2012, 01:28:03 pm »
Effectivement, mon but est de faire en sorte que les deux threads (ou plus) de lecture puissent être actif ensemble et que quand le writer veut écrire, il attend que les lectures soient finies et il commence à écrire...

Je devrai donc utiliser autre chose apparemment... Je vais faire ma mutex personnalisée dans ce cas ;D

ps. Je ne fais pas des choses si poussées, juste un peu :P , mais les performances de cette application sont plus qu'importantes. Un thread ne doit absolument pas s'arrêter si ce n'est pas nécessaire.
« Modifié: Mai 15, 2012, 01:30:00 pm par neo007 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #5 le: Mai 15, 2012, 01:40:24 pm »
Dans ce cas je ne sais pas si tu pourras faire un truc optimisé avec uniquement des mutexs. Il te faudrait en plus de ça au moins des entiers atomiques.

Si tu le peux, utiliser la nouvelle bibliothèque standard (C++11) serait une bonne alternative.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #6 le: Mai 15, 2012, 02:05:42 pm »
Il semblerait que code::blocks intègre cela, mais qu'il faut l'activer manuellement, car c'est encore considéré comme expérimental...(probablement très stable tout de même)

Je vais aller voir de ce côté la semaine prochaine, là je pars à Ottawa en compétition de musique (MusicFest Canada). À bientôt et merci !  :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #7 le: Mai 15, 2012, 02:08:28 pm »
Citer
Il semblerait que code::blocks intègre cela
En fait ce serait plutôt dépendant de la version de GCC que Code::Blocks utilise ;)
Et là tu peux prendre une 4.7 ou une 4.8, qui gère très bien le dernier standard.

Bonne chance pour la compet' ;)
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #8 le: Mai 15, 2012, 11:09:29 pm »
merci :) (j'ai internet à l'hôtel  ;D)

Est-ce que le module network peut supporter 1000 clients ou pas ? certains m'ont dit qu'il n'était pas adapté pour faire ce genre de chose... Seulement, si je regarde blablaland par exemple, ils ont dit eux-même que chacun des mondes étaient un serveur physique...

Qu'en penses-tu ?

De plus, étant donné que mon lock pour l'écriture consiste toujours à supprimer simplement une entrée dans un list, est-ce que ça ne serait pas plus simple de faire boucler le thread jusqu'à ce que ça soit disponible ?

Autrement dit, reprendre le code précédant en changeant les mutex pour des booléen et simplement faire un while(écriture_en_cours);
//plein de code de lecture...

Qu'en penses-tu ? Car dans mon cas, il ne restera jamais très longtemps bloqué puisque il va attendre simplement une lecture (très très rapide donc) ou la lecture va attendre l'écriture (très rapide puisqu'on supprime juste un "pointeur" dans la list).

Merci et bonne journée  :)
« Modifié: Mai 16, 2012, 04:27:13 am par neo007 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #9 le: Mai 16, 2012, 07:37:48 am »
Citer
Est-ce que le module network peut supporter 1000 clients ou pas ?
Ca dépend de ce que tu fais avec ;)

Citer
De plus, étant donné que mon lock pour l'écriture consiste toujours à supprimer simplement une entrée dans un list, est-ce que ça ne serait pas plus simple de faire boucler le thread jusqu'à ce que ça soit disponible ?
Oui c'est une bonne idée, d'ailleurs ça s'appelle un spin-lock. Mais ça requiert des entiers atomiques (pour la variable écriture_en_cours), que le nouveau standard fournit mais pas SFML.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #10 le: Mai 16, 2012, 06:52:15 pm »
Certaines personnes sur le SdZ m'ont dit qu'on pouvait pas écouter plus de 64 sockets avec la SFML à cause de FD_SETSIZE dans une structure FD_SET... ? C'est quoi ça ? Tu pourrais m'expliquer ? :o

Ensuite, aurais-tu un article qui parle des entiers atomiques ou me l'expliquer parce que je comprends pas pourquoi on ne pourrait pas simplement utiliser un booléen... ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #11 le: Mai 16, 2012, 10:23:44 pm »
Citer
Certaines personnes sur le SdZ m'ont dit qu'on pouvait pas écouter plus de 64 sockets avec la SFML à cause de FD_SETSIZE dans une structure FD_SET... ? C'est quoi ça ? Tu pourrais m'expliquer ?
sf::SocketSelector utilise en interne une liste à taille fixe définie par l'OS, et sous Windows effectivement ça peut être 64. Il y a déjà un ticket pour améliorer ça.

Citer
Ensuite, aurais-tu un article qui parle des entiers atomiques ou me l'expliquer parce que je comprends pas pourquoi on ne pourrait pas simplement utiliser un booléen... ?
Il y a sûrement plein d'articles sur le net.
Très simplement : tu tentes de protéger une variable partagée entre plusieurs threads (ta liste) avec... une autre variable partagée (le booléen). Tu te mors la queue, à un moment il te faut une primitive qui soit thread-safe sinon tu ne feras toujours que déplacer le problème vers une autre variable. Et les entiers atomiques sont thread-safe, comme leur nom l'indique.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #12 le: Mai 17, 2012, 04:17:57 am »
D'accord je comprends très bien ce que tu veux dire :) (j'ai pas trouvé de tuto en français du moins sur les entier atomique)

Mais voilà, un entier atomique doit forcément consommer plus en ressource puisqu'il est thread-safe..

Ça serait bien plus léger d'avoir 3 booléens et de changer l'état de ceux-ci et de vérifier leur état si nécessaire non ? Je sais que mon application va toujours posséder un writer et deux readers alors même si mon code n'est pas optimisé à des fins de modification, il va vraiment l'être au niveau des performances non ?

Pas besoin de m'expliquer qu'il s'agit sûrement d'une mauvaise méthode de voir les choses ou je ne sais quoi... J'aimerais simplement savoir si ma façon de faire est effectivement plus efficace que les entier atomique :)

Merci et bonne journée ! ;D

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #13 le: Mai 17, 2012, 10:25:07 am »
Citer
Mais voilà, un entier atomique doit forcément consommer plus en ressource puisqu'il est thread-safe..
Non justement : ils sont implémentés via des instructions du processeur (une seule par opération). Donc ça ne coûte pas un copec. De nos jours tous les processeurs supportent ce genre d'opérations.
Les entiers atomiques sont à la base de pas mal de mécanismes plus complexes. Ils sont utilisés pour implémenter ce que l'on appelle les conteneurs "lock-free" -- ie. qui sont thread-safe sans nécessiter de bloquer les threads.

Et peu importe la manière dont tu veux implémenter les choses autrement, ce ne sera jamais robuste si ce n'est pas basé à un moment où un autre sur une primitive thread-safe.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [SFML2] Besoin d'un petit conseil thread/list.erase
« Réponse #14 le: Mai 17, 2012, 02:01:27 pm »
D'accord, merci beaucoup pour tes conseils et explications : ça devient donc très intéressant comme solution les entiers atomiques :)

 

anything