Problème multi-threading [Résolu]

Signaler
Messages postés
44
Date d'inscription
mercredi 23 mars 2005
Statut
Membre
Dernière intervention
26 avril 2008
-
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
-
Bonjour, comme explicité dans le titre j'ai un problème de multi-threading à savoir que j'ai normalement 3 threads (VCL) qui doivent s'executer en meme temps sauf que ceux-ci s'executent les uns aprés les autres...
Mes trois threads sont construits de la meme façon:

type
 Threadping = class(TThread)
  private
    procedure ping;
  public
    constructor Create(CreateSuspended:boolean);
  protected
    procedure Execute; override;
  end;

implementation

constructor Threadping.Create(CreateSuspended:boolean);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate:=true;
  Priority:=tpNormal;
end;

procedure Threadping.ping;
var
part1,part2,part3,part4,count:integer;
begin
count:=0;
form1.memo2.lines.add('thread1');
part1:=posip(form1.edit1.Text,1);
part2:=posip(form1.edit1.Text,2);
part3:=posip(form1.edit1.Text,3);
part4:=posip(form1.edit1.Text,4)-2;
repeat
inc(count);
inc(count);
application.processmessages;
form1.Label13.Caption:=inttostr(count)+'/'+inttostr(nombrehost);
inc(part4);
inc(part4);
if part4>=254 then
begin
 inc(part3);
 part4:=1;
 if part3>=254 then
 begin
  part3:=1;
  inc(part2);
   if part2>=254 then
   begin
   part2:=1;
   inc(part1);
   end;
 end;
end;
form1.label10.Caption:=inttostr(part1)+'.'+inttostr(part2)+'.'+inttostr(part3)+'.'+inttostr(part4)+'t1';
form1.clping.Host:=inttostr(part1)+'.'+inttostr(part2)+'.'+inttostr(part3)+'.'+inttostr(part4);
form1.clping.ReceiveTimeout:=strtoint(form1.edit4.text);
try
form1.clping.Ping;
if form1.clping.replystatus.BytesReceived>0 then
begin
form1.Memo1.Lines.Add(inttostr(part1)+'.'+inttostr(part2)+'.'+inttostr(part3)+'.'+inttostr(part4));
form1.edit5.Text:=inttostr(form1.Memo1.lines.count);
end;
except
end;
until count>=nombrehost;
end;

procedure Threadping.Execute;
begin
Sleep(500);
synchronize(ping);
end;



Mes threads sont créés de cette facon:


procedure TForm1.Label6Click(Sender: TObject);
var
Thping:Threadping;
thping2:threadping2;
begin
thping:=threadping.Create(false);
thping2:=threadping2.Create(false);
end;



Ce que je ne comprends pas c'est que les procedures appelées par Synchronize s'executent bien en meme temps mais une fois que le dernier thread est créé c'est lui qui prend la main et les autres sont bloqués le temps que la procedure soit terminée, bref l'utilisation des threads n'a plus aucun interet...
En esperant avoir été assez clair et que quelqu'un pourra m'aider, merci.

5 réponses

Messages postés
1023
Date d'inscription
dimanche 1 août 2004
Statut
Membre
Dernière intervention
17 août 2008
1
Salut,

Ceci est le comportement normal de la procédure Synchronize().
Celle-ci permet d'exécuter une procédure non pas dans le thread que tu viens de créer mais dans le thread principal. Ce qui veut dire que la seule utilité du thread que tu as codé est d'appeler une méthode dans un autre thread !

Voila pourquoi elles s'exécutent les unes après les autres.

Le problème, et apparament tu l'as bien compris, c'est que tu ne peux utiliser les composants de tes fiches que depuis le thread VCL, càd celui qui exécute les messages de l'application.

Ce que tu vas devoir faire, c'est créer le composant de ping dans ton thread (dans le constructeur) et utiliser des propriétés pour ne pas devoir utiliser directement les champs de Form1.
Et ton ping s'effectue directement dans Execute()

Ensuite, pour la mise à jour, tu as plusieurs choix:
- Un évènement appelé par une procédure via Synchronize()
- Un message Windows personnalisé.

Eh oui, le mult-threading demande une grande attention quand à la disponibilité des différents blocs de mémoire car si plusieurs threads peuvent modifier une même zone mémoire en même temps, ça devient vite le fouillis total...

Bonne chance,
Florent
Messages postés
44
Date d'inscription
mercredi 23 mars 2005
Statut
Membre
Dernière intervention
26 avril 2008

Merci pour ces explications éclairantes, je pensais que la procédure Synchronize() permetait juste d'éviter que plusieurs threads accèdent en écriture au meme espace mémoire, ceci dit maintenant ca parait assez évident...
Il me reste plus qu'à faire des recherches dans ce sens, merci encore.
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
2
Apres il y a les sémaphores, pour régler les cas d'ecriture d'unevar par plusieurs threads.
Messages postés
1023
Date d'inscription
dimanche 1 août 2004
Statut
Membre
Dernière intervention
17 août 2008
1
Oui DeltaFX mais si c'est juste une question d'affichage, je pense qu'un message devrait largement suffire.
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
2
Tout à fait d'accord. Mais tant qu'à faire autant en mettre, ca mange pas de pain, ca fait de l'entrainement, c'est royalement plus propre, surtout si la machine cible est multicore (paske ces threads tournent pas forcément sur le même proc) et ca fait tout de suite plus style, non ?