IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Thread et property


Sujet :

Langage Delphi

  1. #1
    Candidat au Club
    Profil pro
    particulier
    Inscrit en
    Mars 2003
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : particulier

    Informations forums :
    Inscription : Mars 2003
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Thread et property
    Bonjour

    J'ai besoin d'un renseignement concernant les acces au propriété d'un Thread.

    consideront le Thread suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    type
      PPrgTSK = ^TPrgTSK;
      TPrgTSK = class(TThread)
      private
        FTimeRefresh  : Integer;
      protected
        procedure Execute; override;
      public
        property TimeRefresh: Integer read FTimeRefresh write FTimeRefresh;
        constructor Create;
        destructor Destroy; override;
      end;
     
    procedure TPrgTSK.Execute;
    begin
        while not Terminated do begin
          if TimeRefresh > 0 then Dec(TimeRefresh,1);
        end;
    end;
    Dans cette exemple, on y trouve une proprité "TimeResfresh" qui est lu et écrit par ce Thread (procedure Execute). Mon intérrogation se porte sur l'acces a cette propriété depuis l'extérieur.

    Faut-il prendre des mesures précises (section critique, mutex ...) pour éviter un accès simultanée et donc un déclenchement d'exception lors d'acces à la propriété "TimeRefresh" depuis un click sur un bouton ou alors depuis un autre Thread sous la forme suivante ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Var
      Th : TPrgTSK;
    ...
      Th.TimeRefresh := 200;
    Voilà, j'espère avoir été assez claire et vous remércie d'avance.
    Stbeau.

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Bonjour et bienvenue sur Developpez.com

    Si j'ai bien compris votre problème vous avez une propriété publique dans le Thread dont la valeur est manipulée par ce dernier mais qui peut également être changée depuis l'extérieur.

    Dans ce cas je suggèrerais de définir un accesseur en écriture sur la propriété comme on centralisera l'accès en modification à cette donnée membre ensuite ben ça dépend un peu de comment vous voulez traiter l'accès concurrent. Si c'est juste pour décrémenter correctement une valeur on peut utiliser une section critique mais si c'est plus complexe après il faudrait voir à stocker la valeur ancienne avant de rentrer dans la section critique puis une fois celle-ci ouverte tester si la valeur d'origine est toujours égale à celle actuelle en ce cas faire votre traitement sinon traiter le fait que quelqu'un a modifié la valeur avant vous.

  3. #3
    Candidat au Club
    Profil pro
    particulier
    Inscrit en
    Mars 2003
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : particulier

    Informations forums :
    Inscription : Mars 2003
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Je vous remercie pour votre réponse aussi rapide .

    Stbeau.

  4. #4
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    la solution est la

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Effectivement Edam, le code de SetTickCount donne tout à fait la solution

    Juste une question, quel est risque sur la modification d'une propriété entier en accès direct d'avoir un problème d'écriture ? et même si cela arrive, l'écriture de l'entier ce n'est qu'une seule instruction assembleur MOV, les autres instructions n'étant lié qu'à la recherche du pointeur sur le dit entier selon les mécanismes objets de Delphi, en fait, faudrait que la lecture et l'écriture se produise au même moment dans les deux threads différents que chaque thread soit sur un processeur différent ... c'est vrai que c'est bien de le faire, mais un entier c'est quand même moins sensible qu'un pointeur ou une TList ... je m'en rappele dans mes premiers threads, je m'étais même pas posé la question, je partageais la mémoire à tout va (je n'ai appris les threads à l'école que 6 mois après les avoir découvert en apprentissage chez mon boss de l'époque) ... ce n'est que plus tard en découvrant un problème avec une TList que j'ai découvert qu'il fallait protégé le bousin ...

  6. #6
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 173
    Points
    4 173
    Par défaut
    C'est ce que j'allais dire... ça sert à rien de protéger une opération atomique.

    Juste une remarque quand même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TPrgTSK.Execute;
    begin
        while not Terminated do begin
          if TimeRefresh > 0 then Dec(TimeRefresh,1);
        end;
    end;
    J'espère que ce n'est qu'un exemple et que tu ne feras pas que ça dans ton thread.
    Parce que si TimeRefresh <=0 tu fais une boucle qui va consommer 100% du CPU pour ne rien faire. Dans ce cas, il faudrait au moins faire un petit Sleep pour que windows récupère de la ressource CPU pour les autres threads...

  7. #7
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Si, même les opérations atomiques doivent être protégées, depuis que les multi-processeurs sont arrivés. Cela dit, il y a moyen de protéger une opération atomique plus efficacement qu'avec la lourdeur d'une section critique. Il suffit d'utiliser le modificateur LOCK sur cette instruction.

    Moi j'utilise ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    {*
      Incrémente un compteur de façon thread-safe
      @param I   Compteur à incrémenter
      @return Nouvelle valeur du compteur
    *}
    function InterlockedIncrement(var I: Integer): Integer;
    asm
            MOV     EDX,1
       LOCK XADD    [EAX],EDX
            LEA     EAX,[EDX+1]
    end;
     
    {*
      Décrémente un compteur de façon thread-safe
      @param I   Compteur à décrémenter
      @return Nouvelle valeur du compteur
    *}
    function InterlockedDecrement(var I: Integer): Integer;
    asm
            MOV     EDX,-1
       LOCK XADD    [EAX],EDX
            LEA     EAX,[EDX-1]
    end;
    Remarque : il n'est pas possible d'utiliser LOCK sur un MOV. Met le simple accès en lecture ne doit pas être protégé si les modifications sont toutes faites avec LOCK.

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Joli méthode, c'est vrai que SysUtils.InterlockedIncrement et SysUtils.InterlockedDecrement, on été prévu par Microsoft (repris par Borland pour Kylix) c'est qu'il y a bien une raison,

    Dans SysUtils de Kylix, il y a une variante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function InterlockedIncrement(var I: Integer): Integer;
    asm
          MOV   EDX,1
          XCHG  EAX,EDX
     LOCK XADD  [EDX],EAX
          INC   EAX
    end;
     
    function InterlockedDecrement(var I: Integer): Integer;
    asm
          MOV   EDX,-1
          XCHG  EAX,EDX
     LOCK XADD  [EDX],EAX
          DEC   EAX
    end;
    sous Windows, ces deux fonctions sont des API intégrées dans kernel32

    C'est ce que je disais, c'est bien de le faire car les machines multi-core ou multi-proc même avec une faible probabilité peuvent déclencher cela !

    Citation Envoyé par ShaiLeTroll Voir le message
    ... en fait, faudrait que la lecture et l'écriture se produise au même moment dans les deux threads différents que chaque thread soit sur un processeur différent ... ...

  9. #9
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Dans SysUtils de Kylix, il y a une variante :
    sous Windows, ces deux fonctions sont des API intégrées dans kernel32
    Tiens, j'avais même pas vu que ça existait en standard Je vais pouvoir revoir mon code à l'occasion

Discussions similaires

  1. [Débutant] WPF Thread UI sur dependency property change
    Par kraigoun dans le forum Windows Presentation Foundation
    Réponses: 5
    Dernier message: 10/08/2013, 15h41
  2. Problème de thread et de dependency property
    Par kite37 dans le forum Windows Presentation Foundation
    Réponses: 7
    Dernier message: 06/10/2009, 16h55
  3. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  4. Réponses: 5
    Dernier message: 12/06/2002, 15h12
  5. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo