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 :

Problème d'utilisation du ShowMessage dans un Thread


Sujet :

Langage Delphi

  1. #1
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Points : 4 935
    Points
    4 935
    Par défaut Problème d'utilisation du ShowMessage dans un Thread
    Bonjour,

    Actuellement, je cherche à comprendre le fonctionne des threads pour arriver à mon but, qui est la comprehension des sémaphores ainsi que les mutex.

    Le hic, c'est que je suis loin d'avoir compris quoi que ce soit je crois
    Alors, voilà mon soucis.

    Je suis entrain de lire le PDF sur les threads de Laurent Berne et j'en suis à ses début.

    Je crée mon thread comme ci dessous :
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    unit Unit2;
     
    interface
     
    uses
      Classes,Dialogs;
     
    type
      thread1 = class(TThread)
      private
        { Déclarations privées }
      protected
        procedure Execute; override;
      end;
     
    implementation
     
    { Important : les méthodes et propriétés des objets de la VCL peuvent uniquement
      être utilisés dans une méthode appelée en utilisant Synchronize, comme :
     
          Synchronize(UpdateCaption);
     
      où UpdateCaption serait de la forme 
     
        procedure thread1.UpdateCaption;
        begin
          Form1.Caption := 'Mis à jour dans un thread';
        end; }
     
    { thread1 }
     
    procedure thread1.Execute;
    begin
      ShowMessage('OK! Thread créé');
    end;
     
    end.
    Puis, l'appel comme ceci :
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs,Unit2, StdCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
      MonThread:thread1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      MonThread:=thread1.Create(false);
    end;
     
    end.
    Le hic, c'est que ma méthode ne fonctionne pas (ShowMessage) alors que la méthode de Laurent Berne (MessageBox) fonctionne ...
    Quelqu'un peut m'expliquer le pourquoi ?

    Merci bien

    PS: En fait, le thread me fait des fenêtres non complète ... Rare sont les fois où ça fonctionne correctement...

  2. #2
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Parce que si je ne m'abuse (j'avais réécrit entièrement l'unité Dialogs il y a quelques années pour faire mon propre "look"), ShowMessage utilise des fiches (TMessageForm descendant de TForm), donc utilise la VCL qui n'est pas compatible avec le multithread. Alors qu'un appel direct au MessageBox de l'API Windows ne pose en principe aucun problème. Enfin, je crois modestement que c'est ça.

  3. #3
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Points : 4 935
    Points
    4 935
    Par défaut
    Ah!

    Pourtant, Lorsque je mets ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      MonThread:=thread1.Create(false);
      MonThread.WaitFor;
    end;
    Ca fonctionne
    Une explication ?

  4. #4
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Aucune, en ce qui me concerne... les mystères de la VCL.

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 460
    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 460
    Points : 24 874
    Points
    24 874
    Par défaut
    Le WaitFor attend la fin de l'execution, donc bloque le thread principal, c'est logique que cela fonctionne ! l'objet Application vient pas mettre le foutoir parce qu'une fenêtre a été créé (ben WaitFor bloque vraiement, la boucle Run)

    MessageBox n'est qu'une API windows, cela va créer une fenêtre indépendante (non Delphi), alors que ShowMessage va créer une fenêtre avec comme Owner le TApplication (je te laisse imaginer les partages mémoires), et va donc gérer tout le bousin, c'est à dire que depuis un Thread Secondaire tu modifie la variable globale Application (insertion dans liste components, notification, ...) du Thread Principal, ce qui évidemment sans Synchronize ou Section Critique est extrément risqué !

    Deplus, lorsque ton application sera terminée, il peut parfois vouloir libérer ce ShowMessage, mais le Handle étant alloué dans un thread différent pour Window, il se sont pas valide, donc tu as en plus une Erreur OS 1400, ou une RunTime Error 26 ...


    Pour surveiller un Thread, utilise un Fichier ou OutputDebugString, ou tout autre outil de log thread safe (ce sujet revient souvent sur le forum)

    Ensuite, euh, afficher une fenêtre dans un Thread, euh, ben si la VCL pour ça n'est pas ThreadSafe comme le précise CapJack, c'est parce qu'afficher une fenêtre dans un Thread, ça se fait pas ! Donc inutile d'adapter les fonctions ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Points : 4 935
    Points
    4 935
    Par défaut
    Coucou Shai ! ,

    Citation Envoyé par ShaiLeTroll Voir le message
    Le WaitFor attend la fin de l'execution, donc bloque le thread principal, c'est logique que cela fonctionne ! l'objet Application vient pas mettre le foutoir parce qu'une fenêtre a été créé (ben WaitFor bloque vraiement, la boucle Run).
    Ah d'accord! C'est déjà plus clair.

    Citation Envoyé par ShaiLeTroll Voir le message
    MessageBox n'est qu'une API windows, cela va créer une fenêtre indépendante (non Delphi), alors que ShowMessage va créer une fenêtre avec comme Owner le TApplication (je te laisse imaginer les partages mémoires), et va donc gérer tout le bousin, c'est à dire que depuis un Thread Secondaire tu modifie la variable globale Application (insertion dans liste components, notification, ...) du Thread Principal, ce qui évidemment sans Synchronize ou Section Critique est extrément risqué !

    Deplus, lorsque ton application sera terminée, il peut parfois vouloir libérer ce ShowMessage, mais le Handle étant alloué dans un thread différent pour Window, il se sont pas valide, donc tu as en plus une Erreur OS 1400, ou une RunTime Error 26 ....
    Je comprends mieux le principe! Merci

    Citation Envoyé par ShaiLeTroll Voir le message
    Pour surveiller un Thread, utilise un Fichier ou OutputDebugString, ou tout autre outil de log thread safe (ce sujet revient souvent sur le forum)...
    Je ferai une recherche sur tout ça pour les prochaines choses à venir


    Citation Envoyé par ShaiLeTroll Voir le message
    Ensuite, euh, afficher une fenêtre dans un Thread, euh, ben si la VCL pour ça n'est pas ThreadSafe comme le précise CapJack, c'est parce qu'afficher une fenêtre dans un Thread, ça se fait pas ! Donc inutile d'adapter les fonctions ...
    En effet, afficher une fenêtre dans un thread c'est pas commun! Ba moi j'ai pas faire comme tout le monde (ah ah ah).
    Plu sérieusement, je suis un tuto là dessus, et pour nous montrer la base d'un thread, on a pour exemple d'afficher un message...
    Logiquement, les threads c'est surtout pour faire des calculs ou autre tache qui prennent du temps et qui ne nécessite aucune action de l'utilisateur ...

    Bon, si je résume le tout, ne JAMAIS utiliser les éléments de la VCL dans un thread, utiliser les API Windows le plus souvent pour réduire les plantages et ... heu ... j'ai oublié un truc ou c'est bon ?

    En tout cas, merci pour toutes ces infos!

  7. #7
    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 170
    Points
    4 170
    Par défaut
    Bon, si je résume le tout, ne JAMAIS utiliser les éléments de la VCL dans un thread
    C'est un bon résumé. En général, les appli multithread gèrent l'IHM dans le thread principal et se servent des autres threads pour faire les traitements et calculs.
    Pour qu'un traitement s'effectue dans le contexte du thread principal (afficher un message, mettre à jour l'IHM), tu peux par exemple, utiliser la méthode Synchronize, ou poster un message à ce dernier.

    Actuellement, je cherche à comprendre le fonctionne des threads pour arriver à mon but, qui est la comprehension des sémaphores ainsi que les mutex.
    Je te conseille également de t'intéresser aux sections critiques. Mais attention, l'aide de Delphi (tout comme le PDF cité) sont plutôt source de confusions.
    Les sections critiques (telle qu'elles sont implémentées sous Windows) ne sont rien d'autre que des mutex.
    Elles se distinguent des mutex et sémaphores classiques par leur implémentations : Elles utilisents à la fois un sémaphore et un SpinLock.
    Lorsque tu demandes à acquerir une section critique, elle commence par essayer de verrouiller le SpinLock. Si la section n'est pas disponible, au lieu d'endormir le thread en attendant que la section soit disponible, ce dernier va attendre en bouclant dans le vide (d'où le nom du SpinLock) jusqu'à ce que la section soit libre, ou que le spin est atteind son nombre maximum d'itérations.
    Ainsi, si la section est disponible rapidement, ça évite d'endormir le thread et de lancer une commutation de tâche.
    Par contre, si elle tarde à se liberer, la section critique se met en attente sur un sémaphore pour endormir le thread jusqu'à ce qu'elle soit disponible.

    Les sections critiques sont particulièrements utiles avec les machines multi-processeurs/multi-coeurs, car il est fréquent de protéger de toute petites portions de codes (quelques lignes). Donc en cas de collision, la section sera probablement libérée beaucoup plus vite que ce qu'il faut à Windows pour endormir le thread et ensuite le relancer...
    Par contre, dans un contexte simple coeur/monoprocesseur, elles ne servent à rien et Windows les transforme automatiquement en simple sémaphore en initialisant la valeur du Spin à 0.

  8. #8
    Membre éclairé
    Avatar de nostroyo
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 168
    Points : 680
    Points
    680
    Billets dans le blog
    16
    Par défaut
    Pour la gestion des threads, je ne saurais trop te conseiller d'acheter (ou peut être l'as tu déjà) le livre de teixera et pacheco Delphi6.
    Il y a un super chapitre sur les threads vraiment très bien fait. De toute façon dans ce livre tout est très bien fait, c'est ma bible!

Discussions similaires

  1. Réponses: 3
    Dernier message: 11/04/2008, 22h04
  2. Réponses: 26
    Dernier message: 13/12/2006, 07h35
  3. [C#] Utilisation des données dans un Thread
    Par Seth77 dans le forum C#
    Réponses: 12
    Dernier message: 24/10/2006, 14h14
  4. Problème d'execution de code dans un thread
    Par [Silk] dans le forum Langage
    Réponses: 2
    Dernier message: 06/02/2006, 13h49
  5. Problème d'utilisation de fonction dans une popup
    Par Pymm dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 06/09/2005, 15h00

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