Problème multi-threading

Résolu
OcHre Messages postés 44 Date d'inscription mercredi 23 mars 2005 Statut Membre Dernière intervention 26 avril 2008 - 4 mars 2007 à 10:14
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 - 18 mars 2007 à 10:57
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

florenth Messages postés 1023 Date d'inscription dimanche 1 août 2004 Statut Membre Dernière intervention 17 août 2008 3
4 mars 2007 à 10:56
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
3
OcHre Messages postés 44 Date d'inscription mercredi 23 mars 2005 Statut Membre Dernière intervention 26 avril 2008
4 mars 2007 à 11:23
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.
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
13 mars 2007 à 10:40
Apres il y a les sémaphores, pour régler les cas d'ecriture d'unevar par plusieurs threads.
0
florenth Messages postés 1023 Date d'inscription dimanche 1 août 2004 Statut Membre Dernière intervention 17 août 2008 3
13 mars 2007 à 15:11
Oui DeltaFX mais si c'est juste une question d'affichage, je pense qu'un message devrait largement suffire.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
18 mars 2007 à 10:57
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 ?
0
Rejoignez-nous