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 :

Appel multi-threads d'une DLL = plantage aléatoire ?


Sujet :

Langage Delphi

  1. #1
    cdb
    cdb est déconnecté
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 20
    Points : 11
    Points
    11
    Par défaut Appel multi-threads d'une DLL = plantage aléatoire ?
    Bonjour,

    Soit un exécutable "Delphi" qui lance x threads.
    Chaque thread exécute n fois en boucle une fonction d'une DLL "Delphi".
    La fonction en question prend une chaîne vide et concatène en boucle (500 fois) un caractère en fin de chaîne.
    En cas d'exception dans la fonction DLL ou dans l'appel du thread (méthode Execute) un fichier texte est alimenté avec le message d'erreur.
    Voilà ce que j'obtiens dans ce fameux fichier et ce de façon "aléatoire":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    30/06/2005 10:35:25 > MaFonction: Out of memory
    30/06/2005 10:35:25 > MaFonction: Access violation at address 00A22321 in module 'madll.dll'. Read of address 0146BE80
    30/06/2005 10:35:25 > TMonThread.Execute: Invalid pointer operation
    30/06/2005 10:35:26 > MaFonction: Access violation at address 00A21A6D in module 'madll.dll'. Write of address 00000001
    Pour obtenir ce résultat j'ai lancé 5 threads avec 10000 boucles.
    Bon j'ai lancé plusieurs fois mon programme avant d'obtenir ça mais grosso-modo c'est soit "Access violation" soit "Invalid pointer operation".
    Constatation 1: plus on augmente le nombre de threads ou le nombre de boucles plus on a de chance de tomber sur ce type d'erreur.
    Constatation 2: l'erreur est critique pour l'ensemble du processus (exécutable + DLL).
    Pour ceux qui sont costauds dans tout ce qui touche de près ou de loin aux threads et aux DLL et qui veulent bien m'aider à comprendre (s'il y a bien une explication) vous pouvez télécharger mon projet ici:
    http://www.eaistorage.com/share/download/threadsdll.zip
    Si vous avez la moindre idée ou la moindre piste n'hésitez pas j'aimerai bien élucider ce qui reste pour moi encore un mystère après 5 jours de tests acharnés. Il faut préciser que j'ai vu apparaître le problème dans une architecture bien plus complexe et que j'ai remis en cause pas mal de choses jusqu'à me rendre compte qu'au final avec un projet tout simple j'ai déjà ce phénomène.

    D'avance merci pour vos réponses
    Mathieu
    PS: WinXP SP2 + Delphi 7.0 (4.453)

  2. #2
    Membre éclairé
    Avatar de MD Software
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 613
    Points : 680
    Points
    680
    Par défaut
    Je vais regarder ton code, mais ce que tu racontes laisse à penser à des accès concurenciels. Il faut que tu utilises des sections critiques.
    MD Software
    ---------------------------
    F.A.Q. Delphi - Cours Delphi - Composants Delphi - Sources Delphi

  3. #3
    cdb
    cdb est déconnecté
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Entièrement d'accord avec toi MDS.
    On doit utiliser des sections critiques pour sécuriser les accès concurrentiels possibles sur une zone de donnée partagée entre les threads.
    Mais si tu regardes bien mon source tu t'aperçois que rien n'est partagé donc nul besoin d'utiliser ce genre d'artifice.
    Néanmoins j'ai tenté d'exécuter la fonction de ma DLL en l'entourant par une section critique juste pour vérifier si j'avais toujours l'erreur ou pas. Et bien avec une SC autours de l'exécution de ma fonction pas une seule erreur mais bien évidemment ça ne règle pas le soucis puisque l'intérêt d'utiliser des threads c'est de pouvoir exécuter la fonction de la DLL en parallèle. Mais bon on peut déjà en déduire que le problème vient bien de l'appel simultané par plusieurs threads de la fonction DLL.

    J'ai réalisé le même type de projet mais plutôt que de lancer x threads je lance x exécutables (application console) et là pas une seule erreur. Donc c'est bien le cas particulier d'un appel "multi-threads". Autre solution possible: copier x fois la DLL pour x threads pour que chaque thread charge sa propre DLL (unique) et là encore pas la moindre erreur. Mais cette solution n'est pas exploitable dans mon cas je ne peux pas me permettre de copier des DLL à tout va

    Dernière chose, lorsque j'utilise un PChar plutôt qu'une string "Delphi" dans la fonction de ma DLL plus de problème. Biensûr je ne peux pas m'amuser à revoir toutes mes DLL pour les rendre compatibles elles sont beaucoup trop complexes. Mais en tout cas ça veut bien dire qu'il y a un gros problème quelque part:
    - Chargement de la DLL ?
    - Gestion des threads par Delphi ?
    - Format de la DLL ?
    - ...

    Enfin bref je sèche encore et toujours, j'ai bien essayé de jouer avec les options de projet (côté EXE et DLL) mais rien n'y fait toujours ce plantage "aléatoire" si quelqu'un à une idée je suis preneur

    Merci
    Mathieu

  4. #4
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2002
    Messages
    299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 299
    Points : 373
    Points
    373
    Par défaut
    Mmmm, l'unité de gestion mémoire Delphi, entre les DLL et les programmes Delphi, ne doit pas être thread-safe, tout simplement. Cette unité dont j'ai perdu le nom est nécessaire pour passer les strings delphi entre la DLL et le programme.
    Ceci dit une section critique autour de l'appel à la fonction de la DLL n'empeche nullement l'execution en parallele, simplement elle bloque les autres threads le temps que celui en cours ait fini.

    Tiens je crois que c'est sharemem l'unité à laquelle je pense, et encore une fois developpez.com est notre ami
    http://alphomega.developpez.com/DllString/

  5. #5
    Membre confirmé
    Avatar de lil_jam63
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 447
    Points : 600
    Points
    600
    Par défaut
    Je suis pour les sections critiques également mais travaille avec des pChar plutot que des strings
    ----------------------------------------------------
    Avant de poster, pensez à utiliser les différents outils à votre disposition:
    Google, la FAQ et le moteur de recherche.

  6. #6
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2002
    Messages
    299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 299
    Points : 373
    Points
    373
    Par défaut
    Citation Envoyé par lil_jam63
    Je suis pour les sections critiques également mais travaille avec des pChar plutot que des strings
    En plus ça évite d'être lié au modèle DLL particulier de Delphi, et d'écrire les programmes clients autant que les DLL dans n'importe quel langage. Mais cdb a un existant avec lequel il faut compter. Si Sharemem n'est pas utilisé, il faut l'utiliser. S'il est déjà utilisé partout, restent les sections critiques.

  7. #7
    cdb
    cdb est déconnecté
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par cedricgirard
    Ceci dit une section critique autour de l'appel à la fonction de la DLL n'empeche nullement l'execution en parallele, simplement elle bloque les autres threads le temps que celui en cours ait fini.
    Pour moi ce que tu dis là ressemble à une contradiction
    Si la fonction ne peut être exécutée que par un thread à la fois on otient du séquentiel et non du parallèle. Ok pour utiliser des sections critiques pour l'accès à des zones de données partagées entre les threads mais pourquoi pour l'exécution d'une fonction ?
    Prenons l'exemple d'une foncrion DLL qui transfert par FTP un fichier dont le nom est passé en paramètre. L'idée est de ne pas bloquer un thread qui demande de transférer un fichier de 1Ko alors qu'un autre thread est en train de transférer un fichier de 10Ko par cette fonction de DLL.

    Citation Envoyé par cedricgirard
    Tiens je crois que c'est sharemem l'unité à laquelle je pense, et encore une fois developpez.com est notre ami
    http://alphomega.developpez.com/DllString/

    Bien vu, j'ai lu attentivement le sujet mais mon soucis c'est que moi je n'essaie pas du tout de passer des paramètres de type String dans les fonctions de ma DLL bien au contraire c'est du "full PChar". Je sais pas si vous avez regardé mon projet je vous met là le code de ma fonction DLL de test qui déjà pose problème en "multi-threads":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    procedure MaFonction; stdcall;
    var
      s: String;
      i: Integer;
    begin
      try
        s := '';
        for i := 1 to 500 do begin
          s := s + 'x';
        end;
      except
        on E: Exception do WriteTxt('MaFonction: ' + E.Message);
      end;
    end;
    Non non ne cherchez pas il n'y a pas de paramètre
    Le String dont je parle plus haut est celui qui est déclaré en local dans ma fonction alors je ne sais pas si ça pose problème et si c'est le cas il faut que j'utilise Sharemem pour voir ce que ça donne. Sinon je ne peux pas tout passer en PChar car j'utilise des VCL et unités dans lesquelles j'ai du String de "partout" ce qui semble logique pour des sources Delphi
    Voilà maintenant le code de mon thread qui appelle la fonction:
    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
     
    procedure TMonThread.Execute;
    var
      i: Integer;
    begin
      try
        @FProcMaFonction := GetProcAddress(FHandle, 'MaFonction');
     
        FEvent.WaitFor(60000); // Synchro des threads
        for i := 1 to FLoop do begin
          FProcMaFonction; // Fonction de ma DLL en boucle
        end;
     
      except
        on E: Exception do WriteTxt('TMonThread.Execute: ' + E.Message); // Ecriture dans un fichier texte
      end;
    end;
    Oubliez le WaitFor il est juste là pour démarrer les threads vraiment au même moment.
    FLoop étant le nombre de boucles d'appel de la fonction DLL.
    Je vais tenter de faire le même test sur une fonction qui n'est pas dans la DLL mais directement dans mon projet voir si le problème ne vient pas finalement du multi-threading et non de la DLL.

    D'avance merci pour vos réponses,
    Mathieu

  8. #8
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2002
    Messages
    299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2002
    Messages : 299
    Points : 373
    Points
    373
    Par défaut
    Citation Envoyé par cdb
    Citation Envoyé par cedricgirard
    Ceci dit une section critique autour de l'appel à la fonction de la DLL n'empeche nullement l'execution en parallele, simplement elle bloque les autres threads le temps que celui en cours ait fini.
    Pour moi ce que tu dis là ressemble à une contradiction
    Pas tout à fait, dans la mesure où une section critique doit être la plus courte possible, donc l'enchainement de petites sections conduit à une impression de parralélisme. Souvenons nous que le vrai parallelisme n'existe qu'avec plusieurs processeurs de toute façon. Les SC ne font qu'agrandir certains blocs.

    Citation Envoyé par cdb
    Bien vu, j'ai lu attentivement le sujet mais mon soucis c'est que moi je n'essaie pas du tout de passer des paramètres de type String dans les fonctions de ma DLL bien au contraire c'est du "full PChar". Je sais pas si vous avez regardé mon projet je vous met là le code de ma fonction DLL de test qui déjà pose problème en "multi-threads":
    Désolé, c'est toi qui a parlé de string et pchar, donc j'ai supposé que tu passais des parametres. En interne à la DLL non à priori par besoin de Sharemem.

    Par curiosité, String sur ta machine correspond bien à Ansistring, et non pas à shortstring (celles qui faisaient que 255 caractéres comme sous TPascal). Le WriteTxt correspond à quoi? Si tu fais un affichage IHM dans un thread ça pose soucis : seul le thread primaire en a le droit.

    Citation Envoyé par cdb
    Je vais tenter de faire le même test sur une fonction qui n'est pas dans la DLL mais directement dans mon projet voir si le problème ne vient pas finalement du multi-threading et non de la DLL.
    Bonne idée.

  9. #9
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 67
    Points : 40
    Points
    40
    Par défaut
    bonjour a tous, j ai le meme souci que toi cdb, j ai aussi un access violation, je cherche de mon cote si je trouve je te tiens au courant, merci de faire de meme.

  10. #10
    cdb
    cdb est déconnecté
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Bonjour à tous !

    YAOOOOOOOOOOOOOOOOOOOOO !!!
    oups désolé
    Il faut bien comprendre que je que suis sur le problème depuis 7 jours et j'ai enfin trouvé la solution et le week-end va être bon. Mais prenons les choses dans l'ordre:
    Citation Envoyé par cedricgirard
    Pas tout à fait, dans la mesure où une section critique doit être la plus courte possible, donc l'enchainement de petites sections conduit à une impression de parralélisme. Souvenons nous que le vrai parallelisme n'existe qu'avec plusieurs processeurs de toute façon. Les SC ne font qu'agrandir certains blocs.
    Entièrement d'accord avec toi donc si j'ai une fonction DLL qui peut durer de 1 à 30min je ne dois pas bloquer les threads entre eux avec une section critique au risque de bloquer les "petits" threads (ceux qui demandent peu de temps d'exécution = proche de 1min) face aux "gros" threads (temps d'exécution proche de 30min).
    Citation Envoyé par cedricgirard
    Par curiosité, String sur ta machine correspond bien à Ansistring, et non pas à shortstring (celles qui faisaient que 255 caractéres comme sous TPascal). Le WriteTxt correspond à quoi? Si tu fais un affichage IHM dans un thread ça pose soucis : seul le thread primaire en a le droit.
    Alors mon WriteTxt écrit dans un fichier texte (code basique) donc aucun soucis de synchronisation pour l'accès à des composants graphiques. D'ailleurs ma DLL n'a pas d'interface. Pour ta question à propos du type String voilà la réponse de Delphi:
    Le mot réservé string fonctionne comme un identificateur de type générique. Par exemple :

    var S: string;

    crée une variable S contenant une chaîne. Dans l'état par défaut {$H+}, le compilateur interprète string (quand il apparaît sans être suivi d'un crochet ouvrant) comme désignant AnsiString. Utilisez la directive {$H–} pour que string soit interprété comme désignant ShortString.
    Dans mon cas String = AnsiString mais de toute façon là n'est pas la solution...


    Alors j'ai testé l'appel multi-threads d'une fonction appartenant à mon EXE et non pas à ma DLL. Bien évidemment dans ce cas je n'ai aucun soucis le problème venait donc bien de la DLL. J'ai donc pas mal cherché sur le Web et je suis tombé sur 2 articles très intéressants:
    http://ibphoenix.com/main.nfs?a=ibph...age=ibp_howto5
    http://ibphoenix.com/main.nfs?a=ibph...age=ibp_howto7
    Ils parlent de "thread-safe" dans le cas d'un appel "multi-threads" d'une fonction de DLL ça tombe bien c'est exactement mon architecture
    Grosso-modo ça parle de : threadvar DllProc TlsAlloc/TlsFree/TlsGetValue/TlsSetValue et enfin IsMultiThread (F1)
    Et pour régler mon soucis il m'a juste fallu affecter la valeur True à la variable IsMultiThread de l'unité System dans l'initialisation de ma DLL:
    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
    {*==============================================================================
    Point d'entrée de la DLL
    ===============================================================================}
    procedure DllEntry(Reason : Integer);
    begin
      case Reason of
        DLL_THREAD_ATTACH: ; // Allocation mémoire via TlsAlloc
        DLL_THREAD_DETACH: ; // Désallocation mémoire via TlsFree
      end;
    end;
     
    exports
      MaFonction;
     
    begin
      IsMultiThread := True;
      DllProc := @DllEntry;
    end.
    • NB:
      La procédure DllEntry n'est pas nécessaire je l'ai juste mise là au cas où certains voudraient allouer des zones mémoires côté DLL propres à chaque thread. Cette procédure est appelée 2 fois par chaque thread (ATTACH/DETACH) et permet donc d'allouer des variables locales au thread appelant.
      Si vous lisez le premier article il est précisé que l'utilisation de la directive threadvar (propre à Delphi) n'est pas totalement "Thread-Safe".
      Et qu'il vaut mieux dans ce cas utiliser les fonctions API de Windows qui elles ne posent pas de problème (TlsAlloc, etc.).
      Mais personnellement je ne suis pas passé par cette technique...

    Donc voilà une ligne de code et tout est réglé.
    Pour information cette variable sert également pour un EXE Delphi mais à l'inverse d'une DLL la variable est mise à jour automatiquement dès le moment qu'un thread est lancé par une instance de la classe TThread (ou encore en appelant la fonction BeginThread).

    Merci pour toutes vos réponses !
    Si tu pouvais confirmer mes propos Hypollite76 je serai rassuré pour de bon et je serai sûr de tenir LA solution
    Mathieu
    PS: Si quelqu'un a eu l'occasion d'utiliser les fonctions de l'API Windows...

  11. #11
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par cdb
    PS: Si quelqu'un a eu l'occasion d'utiliser les fonctions de l'API Windows...
    Lesquelles ? Il y en a un paquet, tu sais ? ;-)
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  12. #12
    cdb
    cdb est déconnecté
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par Mac LAK
    Lesquelles ? Il y en a un paquet, tu sais ? ;-)
    Je sais bien...
    Celles dont je parle plus haut et qui sont relatives au sujet à savoir:
    TlsAlloc TlsFree TlsGetValue et TlsSetValue

    Merci

  13. #13
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Ce sont les fonctions de stockage dans l'espace local d'un thread. C'est par exemple là-dedans qu'est stocké le code renvoyé par GetLastError.
    Je les ai déjà utilisées, mais leur usage est plutôt particulier : c'est plutôt pour gérer plein de threads, mais d'une même fonction (=fonction "lancée" plusieurs fois).
    N'est vraiment utile qu'avec des threads Win32, les threads VCL ayant la possibilité d'utiliser des attributs.

    Quel est ton besoin exactement ?
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  14. #14
    cdb
    cdb est déconnecté
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Moi ?
    Pas de besoin particulier pour ce qui est de l'utilisation de ces fonctions API.
    Personnellement je suis passé par une autre technique (comme j'ai dit plus haut) décrite dans un autre sujet que je n'arrive pas à retrouver (peut-être que les sujets non résolus sont supprimés au bout d'un moment car me souvient d'avoir oublier de mettre le tag RESOLU bref...).
    C'était juste pour compléter le sujet et proposer un petit bout de code qui montre comment utiliser ces fonctions (TlsAlloc, TlsFree, ...) dans une DLL appelée par un EXE "mutli-threads". Voilà rien de plus donc si tu as ce bout de code magique bah hésite pas
    Sinon ça peut faire l'objet d'un nouveau sujet car j'en ai trouvé aucun qui traite de ces fonctions...

    Mathieu

  15. #15
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par cdb
    Moi ?
    Ben oui, c'est toi le posteur initial... ;-)

    Citation Envoyé par cdb
    C'était juste pour compléter le sujet et proposer un petit bout de code qui montre comment utiliser ces fonctions (TlsAlloc, TlsFree, ...) dans une DLL appelée par un EXE "mutli-threads". Voilà rien de plus donc si tu as ce bout de code magique bah hésite pas
    J'en ai bien un, mais en C++ et pour une encapsulation de driver.

    Citation Envoyé par cdb
    Sinon ça peut faire l'objet d'un nouveau sujet car j'en ai trouvé aucun qui traite de ces fonctions...
    Si ça peut te "rassurer", même MSDN est relativement avare d'informations sur ces fonctions, et surtout sur leur portée.

    Comme je te l'ai dit, l'intérêt de ces fonctions est (relativement) limité : ce n'est utile que pour stocker des variables/structures dont la valeur peut/va changer de thread en thread, en n'utilisant qu'un index (qui doit être stocké de manière globale au processus) pour récupérer ces valeurs. Un slot alloué par TlsAlloc existe pour le processus entier, y compris pour les threads qui n'existent pas encore, mais pour que tout ça reste cohérent, il est IMPERATIF de ne pas utiliser n'importe quel index pour n'importe quoi ! ;-)

    L'intérêt majeur est, à partir d'un seul élément numérique (le fameux index), d'avoir des fonctions "génériques" dont le déroulement est conditionné au thread appelant, ce qui évite d'avoir à faire transiter une horde de paramètres (pouvant en plus être endommagés !) à chaque fonction. De plus, ces données sont protégées par le système d'exploitation, donc les threads ne peuvent pas "bouffer" les variables des autres threads.

    Chaque slot peut contenir une valeur 32 bits : suivant tes besoins, tu vas y stocker soit un handle quelconque Windows, soit y stocker l'adresse d'une structure plus complexe (et plus grande !) allouée localement par chaque threads, ce qui revient au même que d'avoir une "grosse" zone locale aux threads.

    La complexité d'utilisation est liée au fait d'avoir un système général compatible entre les processus, au sein d'une DLL par exemple : il faut jongler avec les évènements PROCESS_ATTACH et THREAD_ATTACH pour déterminer les index "valides"... Pas forcément simple si tu n'es pas calé en programmation parallèle.

    Attention, le nombre de slots est limité, cf. MSDN.

    Est-ce que ça t'éclaire un peu sur ce sujet ?
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  16. #16
    cdb
    cdb est déconnecté
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Oui c'est cool merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 27/02/2014, 09h53
  2. pb d'appel aux fonctions d'une DLL (visual C++ 6.0)
    Par touti35 dans le forum Visual C++
    Réponses: 4
    Dernier message: 12/12/2006, 09h37
  3. [MFC/C++] Appel de LoadString dans une dll
    Par fleur_de_rose dans le forum Visual C++
    Réponses: 5
    Dernier message: 16/10/2006, 19h44
  4. Appel de fonction d'une DLL en TANSAC SQL
    Par sylvain114d dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 19/01/2006, 10h21
  5. Appel aux fonctions d'une DLL externe ??
    Par Fbartolo dans le forum Access
    Réponses: 7
    Dernier message: 21/11/2005, 17h54

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