Pour ou contre les Mutex ^-^ (Ou les mutex pour les Nuls)

Sujets variés concernant le développement en PureBasic
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: Pour ou contre les Mutex ^-^ (Ou les mutex pour les Nuls

Message par Zorro »

il me semble que meme tes codes "source" ne fonctionnent pas aujourd'hui
il suffit de voir ton editeur visualiseur de code coloré
transformé en fait en code a faire des rectangles de couleurs ... :lol:

quoi? je suis mauvaise langue ? mais non :mrgreen:
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Pour ou contre les Mutex ^-^ (Ou les mutex pour les Nuls

Message par Ollivier »

Cette tordue procédure peut se détecter "threadée" ou "non threadée".

Code : Tout sélectionner

Procedure Proc(*C.Integer)
   CompilerIf Not #PB_Compiler_Debugger
      CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
         ! Mov Rbx, [p.p_C]
         ! Mov QWord [Rbx], Rax
         If *C\I > $1000000000
      CompilerElse
         ! Mov Ebx, [p.p_C]
         ! Mov DWord [Ebx], Eax
         If *C\I > $100000
      CompilerEndIf
            *C\I = 1
         Else
            *C\I = 2
         EndIf
   CompilerEndIf
EndProcedure

; Résultat =
; 0 : Le débogueur m'empêche de savoir
; 1 : Je suis une procédure threadée
; 2 : Je suis une procédure normale (thread principal)

For I = 1 To 0 Step -1
   If I
      Proc(@x)
      WaitThread(CreateThread(@Proc(), @y) )
   Else
      WaitThread(CreateThread(@Proc(), @y) )
      Proc(@x)
   EndIf
   MessageRequester("x = " + Hex(x), "y = " + Hex(y) )
Next
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Pour ou contre les Mutex ^-^ (Ou les mutex pour les Nuls

Message par PAPIPP »

Bonjour à tous

La programmation utilisant des threads est plus rigoureuse que la programmation séquentielle, et l'accès à certaines ressources partagées doit être contrôlé.
Il est donc obligatoire de mettre en place des mécanismes de synchronisation (à l'aide de sémaphores, ou de mutex par exemple),
tout en conservant à l'esprit que l'utilisation de la synchronisation peut aboutir à des situations de deadlock (interblocage) ou livelock (blocage par famine).

Explication succincte du deadlock.
Soit un processus P1 qui utilise une ressource R1 bloque cette ressource aux autres processus.
Soit en même temps un Processus P2 qui utilise une ressource R2 bloque cette ressource aux autres processus.
Si dans le même temps P1 veut accéder à R2 il est bloqué.
Maintenant si P2 veut accéder à la ressource R1 c’est la catastrophe tout est bloqué.

Explication du Livelock.
Soit un processus qui occupe les Ressources R1 ou/et R2 ou/et R3 …ou/et Rn il bloque l’accès à toutes ou à l’une de ces ressources aux autres processus.
Au pire s’ il est dans une boucle infinie c’est à nouveau la catastrophe.
Au mieux s’ il monopolise l’accès pendant tout son temps de processus on à certainement un manque d’optimisation.
( voir ci-dessous l’utilisation abusive des modes de synchronisation)

Voyons plus en détail le problème lié aux ressources communes.
Il existe deux grands types de Ressources.
1) les ressources qui varient pendant tout le temps du processus principal (là où l’on écrit).
2) les ressources qui sont invariables pendant tout le temps du processus principal (Là où on lit seulement.

1) Traitons d’abord les ressources variables elles doivent faire l’objet d’une grande attention car l’ordre de passage des différents processus est très important et les synchronisations sont indispensables.
Tout en évitant les conflits définis ci-dessus (Deadlock ou Livelock)
les solutions pour résoudre en toute quiétude ces Pb sont nombreuses et dépendent de votre propre objectif.
Exemples :Mutex Sémaphore Atomicité(synchronisation à bas niveau) et les Algorithmes Peterson Deker du banquier etc…. Ici on est dans une programmation d’expert.

2) Les ressources qui restent constantes pendant le temps du processus principal n’ont pas dans la majorité des cas à faire l’objet de synchronisation.

Exemple : je ne pense pas que des concepteurs de PB en particulier puissent enclaver dans une synchronisation des constantes comme #PI = 3.1415926535897931 ou #E = 2.7182818284590451.
Il en est de même des noms de variables qui seraient constantes pendant tout le cycle du processus. En effet ces données sont partageables sans aucune synchronisation.

Il reste les ressources qui restent constantes pendant tout le processus par exemple accès à une base de données ou la lecture d’un fichier qui ne sera pas modifié pendant tout le processus.
Je laisse à falsam expert dans les bases de données le loisir de nous parler des synchronisations dans les bases de données utilisées dans le cas de clients-serveur.

Je vais prendre l’exemple le plus simple de la lecture d’un fichier séquentiel qui ne subira aucune modification pendant le processus.
La facilité dans ce cas serait d’utiliser soit un sémaphore soit un mutex. Et le fonctionnement serait assuré sous les conditions de ne pas tomber dan un conflit de type deadlock ou livelock (donc utilisation avec risque).
Mais il y a quelque chose de plus délicat. En effet.

1) ou vous bloquez l’accès à tout le fichier tant que le processus n’a pas fini de lire le fichier. Le temps de blocage peut être très long.(risque de Livelock).

2) ou vous repasser la main après chaque enregistrement traité. Mais alors il faut sauvegarder l’index de l’enregistrement lié à la lecture pour poursuivre le traitement au prochain passage.. mais alors à quoi sert la synchronisation dans ce cas puisque vous avez pris toutes les précautions pour retrouver le dernier enregistrement traité ou à traiter dans ce processus et que vous avez gardé l’enregistrement dans une variable locale propre au processus.et qui peut être retrouvé facilement.

C’est ici que l’on voit l’inutilité de synchroniser d’une manière dogmatique, une étude doit toujours être réalisée avant de prendre une décision.

Voici résumé les principaux inconvénients de la synchronisation écrite par un spécialiste du multithread.
Interblocages apparemment aléatoires :

Si un algorithme est mal conçu et permet un interblocage, le changement de vitesse du processeur, par l'utilisation incomplète d'un quantum de temps alloué ou au contraire de la nécessité d'utiliser un quantum supplémentaire, peut provoquer la situation d'interblocage,
De même, des périphériques plus ou moins rapides que ceux de la machine ayant servi à développer/tester le programme induisent des synchronisations temporellement différentes, et donc peuvent provoquer un interblocage non-détecté auparavant,
Enfin, le changement de charge processeur de la machine (un programme lourd tournant en parallèle, par exemple) peut là aussi déclencher plus facilement des interblocages qui n'avaient pas été vus auparavant, avec l'illusion d'un phénomène aléatoire ;
Complexification inutile de certains algorithmes, qui ne bénéficient pas de la parallélisation du code mais qui sont pénalisés par des synchronisations d'accès aux ressources partagées :
Sur-parallélisation du code alors qu'un traitement séquentiel serait plus adapté, la perte de temps liée à la commutation de contexte n'étant pas compensée par la parallélisation,
Introduction de variables globales, forçant l'utilisation de synchronisation à outrance et donc des commutations de contexte inutiles ;
Sur-utilisation des mécanismes de synchronisation inadaptés là où ils ne sont pas nécessaires, induisant un surcoût de temps processeur inutile :
La mise en œuvre d'un pipeline FIFO entre deux threads seulement peut être effectuée facilement sans aucun mutex,
Utilisation d'une section critique au lieu d'un mutex lecteurs/rédacteur, par exemple lorsque beaucoup de threads lisent une donnée tandis que peu écrivent dedans ou qu'une donnée est plus souvent lue qu'écrite.

A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Répondre