Probleme de Thread

Résolu
cs_manu00 Messages postés 93 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 25 octobre 2006 - 15 oct. 2005 à 09:28
ni69 Messages postés 1418 Date d'inscription samedi 12 juin 2004 Statut Membre Dernière intervention 5 juillet 2010 - 17 oct. 2005 à 16:06
Bonjour,



J'ai un soucis. J'ai fais une boucle dans mon programme qui appelle un Thread:



for i:=0 to (listbox1.Items.Capacity - 1) do

begin

toto:=listbox1.Items.Strings[i];

CNode := treeview1.Items.Add(nil,toto);

MyThread:=TScanThread.Create(false); => ICI

end;



Bon, dans mon thread, je fais une recherche dans la base de registre et je rajoute des choses a la treeview...

Le soucis, c'est que quand je lance cette procedure, elle lance tout
les threads qu'elle peut, et donc me rajoute x fois toto a ma treeview
sans laisser le temps a la recherche dans la Base de Registre de se
terminer.

Ce que je veux en fait, c'est que lorsque dans la boucle, on rentre
dans le thread, on ne puisse pas recommencer la prochaine sequence
boucle (a i+1) sans que le thread se soit terminé de lui même. (en fait
mon thread, c'est juste pour ne pas bloquer l'application...)



J'espere avoir ete clair et j'espere surtout que vous aurez une réponse a mon soucis ;-)



Manu

9 réponses

ni69 Messages postés 1418 Date d'inscription samedi 12 juin 2004 Statut Membre Dernière intervention 5 juillet 2010 12
15 oct. 2005 à 11:56
Salut,

Il existe plusieurs méthodes pour éviter l'exécution simultanée d'un même thread appelé plusieurs fois :









1. Les Sections critiques


Une section critique est un bloc d'instructions qui n'autorise qu'un
seul exétron à la fois à y pénétrer. Exemple :


var // Variables globales de l'unité

CS: TRTLCriticalSection



procedure MaProcedure;

begin

for i:= 0 to (ListBox1.Items.Count - 1) do // Attention tu as fait une erreur ici !

begin

toto: =listbox1.Items.Strings[i];

CNode := treeview1.Items.Add(nil,toto);

MyThread:=TScanThread.Create(false);

end ;

end;



procedure TScanThread.Execute;

begin

EnterCriticalSection(CS); // Début de la section critique

[...] Code du Thread [...]

LeaveCriticalSection(CS); // Fin de la section critique

end;



initialization

InitializeCriticalSection(CS);

finalization


DeleteCriticalSection(CS);





2. Les Mutex


Un mutex ressemble à une section critique mais peut être utilisé entre différents processus.


var // Variables globales de l'unité

hMutex: THandle = 0;



procedure MaProcedure;

begin

for i:= 0 to (ListBox1.Items.Count - 1) do // Attention tu as fait une erreur ici !

begin

toto: =listbox1.Items.Strings[i];

CNode := treeview1.Items.Add(nil,toto);

MyThread:=TScanThread.Create(false);

end ;

end;



procedure TScanThread.Execute;

begin

if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_0 then

begin

[...] Code du Thread [...]

end;

ReleaseMutex(hMutex); // Fin de la section critique

end;



initialization

hMutex : = CreateMutex( nil , False, nil);

finalization


CloseHandle(hMutex);



3. Les Sémaphores

Il existe aussi des Sémaphores qui
possèdent les caractéristiques d'un mutex en y ajoutant un compteur de
ressources (permet à un nombre prédéfini d'exétrons d'entrer de manière
synchronisée dans le bloc d'instructions simultanément). Demande moi si
tu veux un exemple d'utilisation, mais je pense que les Sections
Critiques et les Mutex te suffiront...


@+


Nico { http://www.ni69.new.fr/ }






<hr size ="2" width="100%">

N'oubliez pas de cliquer sur Réponse Acceptée lorsque la réponse vous convient !
3
ni69 Messages postés 1418 Date d'inscription samedi 12 juin 2004 Statut Membre Dernière intervention 5 juillet 2010 12
16 oct. 2005 à 00:40
initialization et finalization se placent à la fin du code, avant le end. final. Par exemple :



procedure Proc1(var1 : integer);

begin

[...]

end;



initialization

[code de la section]

finalization

[code de la section]

end.



<hr size= "2" width="100%">

Si cela ne marche pas, essaye comme ceci :



procedure MaProcedure;
begin

InitializeCriticalSection(CS);

for i: =0 to (ListBox1.Items.Count - 1) do
begin
toto:= listbox1.Items.Strings[i];
CNode := treeview1.Items.Add(nil,toto);
MyThread:=TScanThread.Create(false);
end ;

DeleteCriticalSection(CS);

end;

@+

Nico { http://www.ni69.new.fr/ }




<hr size ="2" width="100%">

N'oubliez pas de cliquer sur Réponse Acceptée lorsque la réponse vous convient !
3
cs_manu00 Messages postés 93 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 25 octobre 2006
15 oct. 2005 à 18:12
Je te remercie beaucoup !! Ca me convient parfaitement :-)

Par contre, juste une question... Le

initialization
InitializeCriticalSection(CS);
finalization
DeleteCriticalSection(CS);



Je le met dans le thread (Scanthread.pas) ou dans le unit1 principal ?

(a vu de pif, je le mettrait dans le thread...)



Merci en tt cas !!



M.
0
ni69 Messages postés 1418 Date d'inscription samedi 12 juin 2004 Statut Membre Dernière intervention 5 juillet 2010 12
15 oct. 2005 à 18:33
Dans le code principal, vu que le thread est créé après l'initialisation et est détruit avant la finalisation du programme

@+

Nico { http://www.ni69.new.fr/ }




<hr size="2" width="100%">

N'oubliez pas de cliquer sur Réponse Acceptée lorsque la réponse vous convient !
0

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

Posez votre question
cs_manu00 Messages postés 93 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 25 octobre 2006
15 oct. 2005 à 19:01
J'ai testé, mais ca ne fonctionne pas.

Je ne sais pas ou mettre initialization et finalization (il me dit Statement expected !)



T'aurais pas une source que je puisse tester le fonctionnement ?

Merci en tt cas pour ta disponibilité.



M.

ps: j'ai vu ton site, trop bien les légo !! ;-)
0
cs_manu00 Messages postés 93 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 25 octobre 2006
17 oct. 2005 à 09:43
Bon, j'ai tout essayé, ca se compile...etc mais pas moyen qu'il se
bloque avant de relancer un thread... Pourtant niveau logique tout y
est, alors je vais continuer à chercher mais je trouve ca bisarre qu'a
aucun moment, ni la criticalsection ni le mutex ne mette en attente un
de mes threads...



Qqlun aurait il une autre méthode sinon ?

Merci encore Nico !



@+

Manu
0
ni69 Messages postés 1418 Date d'inscription samedi 12 juin 2004 Statut Membre Dernière intervention 5 juillet 2010 12
17 oct. 2005 à 11:43
Essaye pour voir de réunir tes deux unités en une, histoire d'avoir la
procédure Execute du Thread dans la même unité que le code appelant...

@+

Nico { http://www.ni69.new.fr/ }




<hr size="2" width="100%">

N'oubliez pas de cliquer sur Réponse Acceptée lorsque la réponse vous convient !
0
cs_manu00 Messages postés 93 Date d'inscription jeudi 19 décembre 2002 Statut Membre Dernière intervention 25 octobre 2006
17 oct. 2005 à 13:02
Bon, j'ai reussi... En fait, c'etait une erreur de prog de ma part...

En tout cas, je te remercie vraiment nico :-) Tu m'a bien aidé...



Bonne journée et encore merci



M.
0
ni69 Messages postés 1418 Date d'inscription samedi 12 juin 2004 Statut Membre Dernière intervention 5 juillet 2010 12
17 oct. 2005 à 16:06
De rien, c'était avec plaisir !

@+

Nico { http://www.ni69.new.fr/ }




<hr size="2" width="100%">

N'oubliez pas de cliquer sur Réponse Acceptée lorsque la réponse vous convient !
0
Rejoignez-nous