Synchronization des Threads

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Laulite
Messages : 26
Inscription : mer. 06/juin/2007 21:27
Contact :

Synchronization des Threads

Message par Laulite »

Je suis en train de programmer une console lumière qui exploite beaucoup les threads, et j'aimerais avoir des conseils pour leurs synchronisations

Principe: Plusieurs Registres définissant des états lumineux ( 1 Registre=512 Octets) sont manipulés en temps réels par l'utilisateur. Ces registres sont mixés dans un registre de sortie, et ceci à "haute" fréquence (30fps).
plusieurs threads tournent en parallèles:
-Le programme principal pour la manipulation des registres par l'utilisateur
-un thread de mixage
-un thread d'affichage
-un thread de gestion de la sortie interface

Pour l'instant, je ne synchronise rien, le programme n'est pas compilé en threadSafe (Une librairie m'y en empêche).
Mes questions:
-Que fait l'option threadsafe? est-ce que cela synchronise les threads automatiquement? Cela remplace-t-il une synchronisation par mutex?

-La synchronisation par mutex est-elle obligatoire? Après analyse du fonctionnement de mon programme, il n'y a jamais deux threads qui écrivent en même temps dans le même registre. Quand deux threads se croise sur un registre, il y en a un en lecture, l'autre en écriture, où les deux en lecture. Alors je me disais qu'il n'y avait pas forcement de conflits...

Merci à ceux qui ont une bonne connaissance de ces problèmes de me donner leur avis, cela me permettra de prendre une décision avant de continuer la programmation
Dernière modification par Laulite le dim. 15/juil./2007 18:23, modifié 1 fois.
Le boeuf est lent mais la terre est patiente
Avatar de l’utilisateur
Droopy
Messages : 1151
Inscription : lun. 19/juil./2004 22:31

Message par Droopy »

Pour les thread il y a ça :

Code : Tout sélectionner

;/ Hardy

Global WithMutex,WithoutMutex

Global Mutex1 ;/ Définition en global du Handle du Mutex
Mutex1=CreateMutex_(0,0,"Mutex1") ;/ Création du Mutex

Procedure With2(Value)
    sleep_(Random(100))
    WaitForSingleObject_(Mutex1,-1) ;/ Attends que le mutex soit libre / s'en empare (-1 = attens infiniment (#INFINITE) )
    WithMutex+Value ;- Zone gérée par le Mutex
    ReleaseMutex_(Mutex1) ;/ Libération du mutex( laisse les autres threads ), seul un thread peut faire ça
  EndProcedure
  
  Procedure Without(Value)
    sleep_(Random(100))
    WithoutMutex+Value
  EndProcedure
  
  NewList Tid()
  
  For n= 1 To 10000
    
    AddElement(Tid())
    Tid()=CreateThread(@With2(),1)
    AddElement(Tid())
    Tid()=CreateThread(@With2(),-1)
    
    AddElement(Tid())
    Tid()=CreateThread(@Without(),1)
    AddElement(Tid())
    Tid()=CreateThread(@Without(),-1)
    
  Next
  
  ForEach Tid()
    WaitThread(Tid()) ;/ Attends que tous ls threads soient terminés
  Next
  
  MessageRequester(Str(CountList(Tid()))+" Threads géré par Mutex","With "+Str(WithMutex)+#CRLF$+"Without "+Str(WithoutMutex))
  
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message par brossden »

Je dis certainement une connerie mais pourquoi faire plusieurs threads s'ils sont synchronisés ?

Si un déphasage est necessaire et il suffit de generer un decalage dans le temps de plusieurs variables.
Soit ce sont des harmoniques et il suffit de prendre un fréquence trés élevée de même valeur que l'harmonique la plus haute et faire de simple division, via des modulos ...

Si je me plante serait il possible de tracer un diagramme des ces threads pour que je comprenne mieux le problème ?
Denis

Bonne Jounée à tous
Laulite
Messages : 26
Inscription : mer. 06/juin/2007 21:27
Contact :

Message par Laulite »

quand je dis synchronisé ce n'est pas en terme d'harmonique ou de fréquence, mais en terme d'accès mémoire. C'est vrai que le terme n'est pas heureux mais je n'ai pas trouvé mieux. Le fond de ma question est:
est-ce grave si un thread ecrit dans une zone mémoire alors qu'un autre est en train de lire la même zone? Va-t-il y avoir conflit et bug? car pour ce qui est du résultat, cela ne me parait pas grave s'il y a des chevauchement entre lecture et écriture, puisque celles ci se répètent à haute fréquence.
Le boeuf est lent mais la terre est patiente
KarLKoX
Messages : 1191
Inscription : jeu. 26/févr./2004 15:36
Localisation : France
Contact :

Message par KarLKoX »

Dans ce cas, l'exemple de Droopy explique exactement ce que tu recherches, c'est ce que l'on appel l'exclusion mutuel.
"Qui baise trop bouffe un poil." P. Desproges
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message par brossden »

Je ne vois pas en quoi il y aurait problème sachant que le multitache n'existe pas c'est du temps partagé avec passage d'un process à l'autre ce qui fait que je vois mal un processeur capable de traiter une lecture et une ecriture simultanéement, je pense que c'est un faut problème.
Quand à dire que 30 Hz c'est une haute fréquence ???? Je te rappelle que la fréquence d'horloge des processeurs actuel est en général bien au dela de 1 Go Hz ce qui veut dire que même s'il faut 100 000 pulses pour traiter une opération ce qui est somme toute trés important, tu obtiens encore 10 000 traitements à la seconde donc 10 000/30 =300 fois ce dont tu as besoin !
Denis

Bonne Jounée à tous
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

brossden a écrit :Je ne vois pas en quoi il y aurait problème sachant que le multitache n'existe pas !
tu ne confond pas multitache et parallélisme (transputer) ? :)

pour rappel :
Le terme multitâche intervient au niveau logique (système d'exploitation) et est indépendant du nombre de processeurs présents physiquement dans l'ordinateur (multiprocesseur).

La simultanéité apparente est le résultat de l'alternance rapide d'exécution des processus présents en mémoire. Le passage de l'exécution d'un processus à un autre est appelé commutation de contexte. Ces commutations peuvent être initiées par les programmes eux-mêmes (multitâche coopératif) ou par le système d'exploitation lors d'événements externes (multitâche préemptif).
pour ce qui concerne, la simultaneité d'une lecture ecriture
si l'on se place d'un point de vue microscopique absolue, effectivement cela ne peut avoir lieu en meme temps, a moins d'avoir plusieurs processeurs !!
(ou plusieurs coeurs ?)

mais d'un point de vue "humain" macroscopique et tenant compte de l'architecture d'un ordinateur , il pourrai y avoir effectivement conflit
car il ne faut pas oublier le principe des buffers et de la latence qui va avec..., et dans ce cas, il peut y avoir ecriture et lecture d'une meme case memoire, ou d'un meme emplacement disque dur, ce qui est facheux ! :)
c'est d'ailleurs la raison d'etre des threads et des Mutex !! :D
KarLKoX
Messages : 1191
Inscription : jeu. 26/févr./2004 15:36
Localisation : France
Contact :

Message par KarLKoX »

brossden a écrit :Je ne vois pas en quoi il y aurait problème sachant que le multitache n'existe pas c'est du temps partagé avec passage d'un process à l'autre
C'est la définition du multitâche préemptif mais la tu confonds processus et thread : il ne peut y avoir un processus sur un autre SAUF les processus léger (thread) justement, qui eux, appartiennet au même processus parent et partagent donc le même contexte/ressource et il peut dans ce cas y avoir acces mutuel car il n'y a pas de changement de contexte car il reste le même.
"Qui baise trop bouffe un poil." P. Desproges
Laulite
Messages : 26
Inscription : mer. 06/juin/2007 21:27
Contact :

Message par Laulite »

Bon, Ok 30fps c'est pas de la haute fréquence.
Si j'ai bien compris l'exemple de Droopy, il tend à prouver que le résultat est le même avec ou sans mutex. J'ai essayé avec des buffer de 512 long, le résultat est le même.
Donc, à priori, il n'aurait pas de conflit machine lors d'une supposé lecture/ecriture simultanées. L'interêt des mutex serait donc seulement algorythmique; Dans mon cas, ce n'est pas grave si les lectures et écritures se croisent sur les même buffers...Pour ma part, la discussion reste ouverte.

Quand est-il de l'option threadSafe? Je n'arrive pas à saisir précisement son action....
Le boeuf est lent mais la terre est patiente
KarLKoX
Messages : 1191
Inscription : jeu. 26/févr./2004 15:36
Localisation : France
Contact :

Message par KarLKoX »

Si tu veux voire une différence, regarde l'exemple donné à la fonction CreateMutex.
"Qui baise trop bouffe un poil." P. Desproges
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Laulite a écrit : Quand est-il de l'option threadSafe? Je n'arrive pas à saisir précisement son action....
si je me souviens bien,c'est en rapport avec l'utilisation des chaines de characteres !!


voir ici :
http://www.purebasic.fr/french/viewtopi ... readd+safe
Laulite
Messages : 26
Inscription : mer. 06/juin/2007 21:27
Contact :

Message par Laulite »

J'ai regardé l'exemple de createmutex(), effectivement, cela change le résultat. Mais comme chez moi cela ne change rien au résultat que cela soit programmé avec ou sans mutex, je voulais savoir s'il pouvait y avoir des conflits machine si deux threads manipulent la même variable globale. Dans l'exemple proposé, il n'y a visiblement pas conflit.
Tout ça parce que je redoute de me lancer dans la synchronisation par mutex, car cela me semble assez piegeux au niveau programmation... Alors si je pouvait éviter...

Bon Voilà un autre essai où deux threads manipulent en parallèle la même variable. Résultat concluant sans Mutex. Cela donne une idée de la différence de temps de calcul, du simple au double.

Code : Tout sélectionner

#NbreBoucle=2000
#Delay=5
Global  AvecMutex
Global  SansMutex

Global Mutex
Mutex=CreateMutex()


Procedure SansMutex(Valeur)
  For i=1 To #NbreBoucle
    ;PrintN("Sans"+Str(Valeur)+"-->"+Str(i))
    SansMutex+Valeur
    Delay(#Delay)   
  Next i
EndProcedure

Procedure avecMutex(Valeur)
  For i=1 To #NbreBoucle
    ;PrintN("Sans"+Str(Valeur)+"-->"+Str(i))
    LockMutex(Mutex)
    AvecMutex+Valeur
    Delay(#Delay)
    UnlockMutex(Mutex)
  Next i
EndProcedure

OpenConsole()

PrintN("2 Threads inverse, sans mutex")
Debut=ElapsedMilliseconds()
ThreadPlus=CreateThread(@SansMutex(),1)
ThreadMoins=CreateThread(@SansMutex(),-1)
WaitThread(ThreadPlus)
WaitThread(ThreadMoins)
Fin=ElapsedMilliseconds()
TempsSansMutex=Fin-Debut

PrintN("2 Threads inverse, avec mutex")
Debut=ElapsedMilliseconds()
ThreadPlus=CreateThread(@avecMutex(),1)
ThreadMoins=CreateThread(@avecMutex(),-1)
WaitThread(ThreadPlus)
WaitThread(ThreadMoins)
Fin=ElapsedMilliseconds()
TempsAvecMutex=Fin-Debut

PrintN("Sans mutex  Resultat="+Str(SansMutex))
PrintN("Temps de Calcul="+Str(TempsSansMutex))
PrintN("")

PrintN("Avec mutex  Resultat="+Str(AvecMutex))
PrintN("Temps de Calcul="+Str(TempsAvecMutex))
PrintN("")
Input()

Le boeuf est lent mais la terre est patiente
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message par brossden »

Je suis désolé de contredire pas mal de gens ici mais :
Un processuer ne fait qu'une seul chose à la fois !
Deux processeur ou même les deux coeur dans un dual core ne peuvent pas avoir accès au bus en même temps alors ??? il y en a forcément un qui verouille l'accès à l'autre ne seraitce qu'un cyce d'horloge avant ! Je ne vous explique pas le bordel et surtout les court circuit si une piste du bus était forcé à + 5 volts par un processueur et mis à la masse par un autre ! Ca fumerait un poil ! :lol:
Deplus Mutex ou pas cela reste de la programmation donc executé par les processeurs donc où est le verrouillage anti chevauchement ?

Les définitions de multitache de chacun, ici ne font que confirmer que ce dernier n'existe pas !
Denis

Bonne Jounée à tous
Laulite
Messages : 26
Inscription : mer. 06/juin/2007 21:27
Contact :

Message par Laulite »

En pratique, mon programme tourne sans mutex et sans problême:
20 registres de 512 Octets, manipulés simultanément en écriture/lecture par 4 threads, à 40fps....... et pas de bugs....Denis, je crois bien que tu as raison
Le boeuf est lent mais la terre est patiente
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

je pense que les Mutex sont utile, pour les acces aux peripheriques, qui sont remplis de Buffer Hard !!
et dont l'ecriture-lecture peuvent a cause d'un buffer, arriver en meme temps !!

1 je lance une ecriture longue
2 je lance une lecture rapide
3 je relance une ecriture longue (mince la premiere ecriture n'as pas fini !!)

c'est d'ailleurs pourquoi Windows protege un fichier ouvert en cours

mais je reste persuadé qu'il est possible d'avoir des erreurs importante
si des threads ou timer sont employé pour plusieurs lecture-ecriture

soit dans la ram, soit sur un périphérique quelconque ... :)
Répondre