6
votes

Delphi Filetage - Quelles parties du code doivent être protégées / synchronisées?

Jusqu'à présent, je pensais que toute opération effectuée sur un objet «partagé» (commun pour plusieurs threads) doit être protégée par «synchronisation», quoi qu'il arrive. Apparemment, j'avais tort - dans le code que j'étudie récemment, il y a beaucoup de classes (thread-coffre-fort, que l'auteur affirme) et une seule partie utilise une section critique pour presque toutes les méthodes.

Comment puis-je trouver quelles parties / méthodes de mon code doivent être protégées avec la critique (ou toute autre méthode) et qui non?

Jusqu'à présent, je n'ai pas trébuché sur une note d'explication / article / blog intéressante, tous les résultats de Google sont les suivants:

a) Exemples de synchronisation entre le fil et l'interface graphique. De la simple barre de progression à la plupart complexe, mais la leçon est toujours évidente: chaque fois que vous accédez / modifiez la propriété de la composante GUI, faites-le dans "Synchroniser". Mais rien de plus.

B) Articles expliquant des sections critiques, des mutiles, etc. juste une approche différente de la protection / synchronisation.

c) Exemples de classes de fil-sécurité très très simples (pile de fil de fil ou liste) - ils font toutes les mêmes - implémenter des méthodes de verrouillage / déverrouillage qui entrent / laissent la section critique et renvoient le pointeur de la pile / de la liste réelle sur le verrouillage .

maintenant je cherche une explication quelles parties du code doivent être protégées .

pourrait être sous forme de code;) mais s'il vous plaît ne me fournissez pas une autre "utilisation de synchroniser pour mettre à jour la barre de progression" ...;)

Merci!


0 commentaires

5 Réponses :


5
votes

Vous demandez des réponses spécifiques à une question très générale.

En gros, à l'exception des opérations d'interface utilisateur, vous devez protéger chaque accès de mémoire / ressources partagée pour éviter deux threads potentiellement concurrents à: p>

  • Lire la mémoire incohérente li>
  • écriture de la mémoire en même temps li>
  • Essayez d'utiliser la même ressource en même temps à partir de plusieurs threads ... jusqu'à ce que la ressource soit en sécurité. LI> ul>

    En règle générale, je considère toute autre opération de fil d'opération, y compris les opérations qui n'accèdent pas à la mémoire partagée ou non d'objets partagés. P>

    Par exemple, considérez cet objet: P>

    type
      TThrdExample = class
      private
        FValue: Integer;
      public
        procedure Inc;
        procedure Dec;
        function Value: Integer;
        procedure ThreadInc;
        procedure ThreadDec;
        function ThreadValue: Integer;
      end;
    
    ThreadVar
      ThreadValue: Integer;
    


6 commentaires

Je ne veux pas de réponse plus spécifique. En fait, je cherche même plus de généralités. J'ai besoin d'apprendre beaucoup sur le threading, et je cherche un bon "point d'entrée";) Surtout depuis que j'utilise Delphi depuis la version 6 et jamais jamais vu la déclaration de Threadvar ...


@Migajek: Non, le troisième point est correct. Jachgue dit ce que deux threads pourraient faire cela nécessiterait une synchronisation.


@Michael merci. Lire le point entier à nouveau aidé; p c'est parce que 2 suis-je, je suppose ...


@MIGAJEK: Pas sûr de quelle version introduite la version threadvar ... peut-être que Delphi 5, je ne peux tout simplement pas se souvenir.


@jachguer: Les champs entier ne sont que des atomiques s'ils sont alignés sur une limite D Lorsque le threading est impliqué, il vaut mieux pécher du côté sûr.


@Lieven: Vous avez raison à propos de Err sur le Sécuritaire ... Je suis d'un programmeur défensif genre



2
votes

Vous avez mal compris Tthread.Synchroniser la méthode.

TTHead.Synchroniser et TTHead.Queue Méthodes exécute du code protégé dans le contexte du fil principal (GUI). C'est pourquoi vous devez utiliser Syncronize ou la file d'attente pour mettre à jour des contrôles de l'interface graphique (comme ProgressBarbar) - Normalement, seul le thread principal doit accéder aux contrôles de l'interface graphique.

Les sections critiques sont différentes - le code protégé est exécuté dans le contexte du fil qui a acquis une section critique, et aucun autre thread n'est autorisé à acquérir la section critique jusqu'à ce que l'ancien fil le libère.


0 commentaires

2
votes

Vous utilisez une section critique en cas de besoin d'un certain ensemble d'objets à mettre à jour atomiquement. Cela signifie, ils doivent à tout moment être déjà mis à jour complètement ou pas encore mis à jour du tout. Ils ne doivent jamais être accessibles dans un état de transition.

Par exemple, avec une simple lecture / écriture entier, ce n'est pas le cas. Le fonctionnement de la lecture entier ainsi que le fonctionnement de l'écriture Il est déjà atomique: vous ne pouvez pas lire entier au milieu du processeur l'écrivant, à moitié mis à jour. C'est une valeur ancienne ou une nouvelle valeur, toujours.

Mais si vous voulez incrément l'entier atomique, vous n'en avez pas une, mais trois opérations que vous devez faire à la fois: lisez l'ancienne valeur dans le cache du processeur, incrémentez-la et écrivez-le à la mémoire. Chaque opération est atomique, mais les trois d'entre elles ne sont pas.

Un thread peut lire l'ancienne valeur (dire, 200), l'incrémentez-la par 5 dans le cache, et en même temps qu'un autre thread pourrait également lire la valeur (toujours 200). Ensuite, le premier thread écrit 205, tandis que le deuxième fil augmente sa valeur mise en cache de 200 à 203 et écrit 203, écrasement 205. Le résultat de deux incréments (+5 et +3) devrait être de 208, mais il est 203 en raison de -atomicité des opérations.

Ainsi, vous utilisez des sections critiques lorsque:

  1. une variable, un ensemble de variables ou une ressource est utilisée à partir de plusieurs threads et doit être mis à jour atomiquement.
  2. Ce n'est pas atomique par lui-même (par exemple, appeler une fonction surveillée par une section critique à l'intérieur du corps de la fonction, est déjà une opération atomique)

0 commentaires

1
votes

1 commentaires

Ce domaine semble avoir dépassé le côté obscur et est maintenant un portail des sites Web de l'annonceur. Les tutoriels peuvent être obtenus à CC.EMBARCADERO.com/Townload.aspx?id=14809 < / a>. Vous aurez besoin d'un identifiant CDN pour télécharger le fichier ZIP, qui contient le guide multithreading au formulaire HTML, ainsi que des exemples de code.



0
votes

Si vous utilisez la messagerie pour communiquer entre les threads, vous pouvez absolument ignorer complètement les primitives de synchronisation, car chaque thread accède uniquement à ses structures internes et aux messages eux-mêmes. En substance, c'est une architecture beaucoup plus facile et plus évolutive que d'utiliser des primitives de synchronisation.


0 commentaires