Page 2 sur 3

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 13:25
par Backup
Fred a écrit :Pour ainsi dire, KillThread() n'est jamais une bonne solution, car la memoire allouée par le thread (sa propre pile) n'est pas désallouée. C'est une commande à utiliser uniquement quand il y a un vrai probleme (le thread est bloqué etc.).

Alors là, faut donner une solution par contre !!

dans l'exemple que j'ai mis en couleur
on lance le trhead avec un bouton
et pour le quitter on use d'un autre bouton

sans KillThread() tu fait comment ?

pour moi (dans mon esprit) la creation d'un thread
amenait forcement la destruction de celui-ci
sinon bonjour la multiplication des threads
si plusieurs appels sont effectués ...

faudrai obligatoirement utiliser les mutex ?

d'autre par , pourquoi KillThread() ne libere pas tout ?
ne serai-ce faisable ?

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 13:54
par nico
Dans mon code alternate data stream où j'utilise une procédure récursive, j'ai placé une variable globale qui lorqu'elle passe à un met fin à la procédure mais qui permet à la procédure de se terminer normalement.
Voir le code.

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 14:17
par Backup
je comprends bien le principe de faire se terminer la procedure
(meme par un Procedurereturn)

mais si on ne kill pas le thread , que deviens t'il ??

a la prochaine relance, il s'accumule dans la ram. avec un autre iD.!?

ou alors le simple fait de quitter la procedure , termine le thread ?
(que l'on pourrai alors recreer a nouveau.. )

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 14:33
par Ar-S
je serai aussi curieux d'avoir la réponse.

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 14:38
par MLD
Ar-S a écrit :je serai aussi curieux d'avoir la réponse.
Ben moi aussi

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 15:04
par Fred
Un thread se termine correctement des qu'il sort de la procedure qui est passée à CreateThread(). Donc l'idée pour terminer convenablement un thread est de lui faire quitter sa procedure mere, soit via un ProcedureReturn, soit en quittant la boucle via une variable global ou un evemenet etc.

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 15:47
par MLD
Merci Fred
Je note

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 16:32
par Ar-S
Pour être sûr, est-ce que celà est ok ?

Code : Tout sélectionner

global toto
toto=1

procedure Thread_et_sort(*bidule)
  repeat
    MessageRequester("test","numéro "+str(toto))
    toto+1
  until toto=3
  ProcedureReturn toto
EndProcedure

CreateThread(Thread_et_sort(*bidule),100)

end

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 16:37
par Fred
oui c'est ca. Le "ProcedureReturn toto" ne sert à rien car on ne peut pas recuprer la valeur de sortie d'une procedure threadée.

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 16:41
par Ar-S
ok, ça se décante dans mon citron. :wink:

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 16:41
par Jacobus
En utilisation dans un programme fenêtré on aurait donc ce genre de chose :

Code : Tout sélectionner

Enumeration 
  #Win
  #Text_time
  #btn_go
  #btn_stop
EndEnumeration 

Global var$ = ""

Procedure Thread_count(*param)
  For a = 1 To 15000
    SetGadgetText(#Text_time," Time = "+Str(a))
    If var$ = "stop"
      Break
    EndIf     
  Next   
  SetGadgetText(#Text_time," Time = "+Str(a)+Chr(13)+"Thread stoppé!") 
EndProcedure 

If OpenWindow(#Win, 0, 0, 300, 100, "Thread", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) <> 0  
  ButtonGadget(#btn_go,10,20,80,25,"Démarrer"):GadgetToolTip(#btn_go,"Lancer le Thread")  
  ButtonGadget(#btn_stop,10,50,80,25,"Stopper"):GadgetToolTip(#btn_stop,"Forcer l'arrêt du Thread")  
  TextGadget(#Text_time,100,20,190,60,"",#PB_Text_Border|#PB_Text_Center)
  SetGadgetColor(#Text_time,#PB_Gadget_BackColor,RGB(23, 33, 41))
  SetGadgetColor(#Text_time,#PB_Gadget_FrontColor,RGB(189, 193, 200))  
  If LoadFont(3,"Courier new",9,#PB_Font_HighQuality|#PB_Font_Bold)
    SetGadgetFont(#Text_time,FontID(3))
  EndIf  
EndIf 

Repeat 
  Event = WaitWindowEvent()
       
   If Event = #PB_Event_Gadget     
     Select EventGadget()   
         
       Case #btn_go : var$ = "go" : CreateThread(@Thread_count(),0)
         
       Case #btn_stop : var$ = "stop"
         
    EndSelect    
   EndIf            
 Until Event = #PB_Event_CloseWindow 
End 


En effet c'est pratique, mais qu'en serait-il d'une fonction telle que CopyDirectory() dans la procédure?
Comment savoir qu'elle est en cours ou terminée pour faire le break en cas d'appui sur "Stop" par exemple?

Prenons cet exemple de procedure pour le thread :

Code : Tout sélectionner

Procedure ThreadCopier(*param)    
  Dossier1$ = "Mondossier 1"  
  Dossier2$ = "Mondossier 2" 
  CopyDirectory(Dossier1$, Dossier2$+"\", "*.*", #PB_FileSystem_Recursive|#PB_FileSystem_Force)  
EndProcedure
Comment arrêter le thread si le dossier à copier fait plusieurs Go et qu'on veut pas attendre ??

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 17:44
par Malo
Merci Fred de te pencher également sur ce problème

Quand j'ai mis le code avec une boucle dans la procédure " CompteTjrs() " c'était pour donner du temps pour montrer mon problème; " comment quitter à tout moment la procédure lancer avec le boutonValider ", s'il n'y avait pas cette boucle on aurait rien vu. Je pensais que la solution aurait été simple.

Dans cette procédure en réalité, je lis un fichier texte, qui peut être de différentes tailles, avec des valeurs , que je manipule,
pour en sortir une présentation sous excel via ComatePlus.
Tout fonctionne très bien , sauf que si la personne à choisit un mauvais fichier ,il lui faut la possibilité de stopper l'opération.

Le problème dans ce cas, si je comprend bien , puisse que le code de ma procédure n'est pas dans une boucle principale l'emploie du Break n'est pas approprié , je devrais mettre une variable avec une condition à différent endroit dans le code, pour pouvoir stoper le Thread .

C'est vrai que le coup du KillThread fonctionnait bien a priori.....mais bon....

Re: Comment stopper une procédure

Publié : dim. 19/sept./2010 20:33
par case
on peux faire comme ca par exemple

Code : Tout sélectionner

Declare Thread_count(*file.string)
main=OpenWindow(#PB_Any,0,0,150,100,"test",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ouvrir=ButtonGadget(#PB_Any,0,0,150,20,"ouvrir un fichier")
Global alert=0
Repeat
  ev=WaitWindowEvent()
  Select ev
    Case #PB_Event_Gadget
      Select EventGadget()
        Case ouvrir         
          file.string\s=OpenFileRequester("","","",1)
          alert=0
          stop=ButtonGadget(#PB_Any,0,20,150,20,"STOP !")
          CreateThread(@Thread_count(),file)
          DisableGadget(ouvrir,01)
        Case stop
          alert=1
          FreeGadget(stop)
          DisableGadget(ouvrir,0)
      EndSelect
  EndSelect
  
Until ev=#PB_Event_CloseWindow

Procedure Thread_count(*file.string)
  rd=ReadFile(#PB_Any,*file\s)
  If rd  
    Repeat
      Debug "read "+*file\s
    Until Eof(rd) Or alert=1 ; on atteindra jamais la fin du fichier car on ne le lis pas vraiment
    closefile(rd)
  EndIf
EndProcedure 

Re: Comment stopper une procédure

Publié : lun. 20/sept./2010 18:44
par Malo
Oui Case, cela peut être une solution , mais mon problème si je mets beaucoup de code dans la boucle
Repeat, le programme va executer le code, ce qui parrait normal, avant de voir le Until.

En mettant une variable avec une condition , à plusieurs endroit clé dans le code, je sors de la procédure
sans problème, même si ce n'est pas très élégant, mais au moins je ne tue plus le thread, comme le recommande Fred.

Re: [RESOLU] Comment stopper une procédure

Publié : mer. 02/mars/2011 1:01
par Ar-S
Je relance ce petit topic sur les thread et les arrets de procédure.
Pourquoi mes "MessageRequester()" n'apparaissent-il pas ?

Code : Tout sélectionner

Global toto.l
toto=1

;Declare WorkingProgress(*bidule)

Procedure.l WorkingProgress(*bidule)
  Repeat
    Debug "toto"
    MessageRequester("test","numéro "+Str(toto))
    toto+1
  Until toto=3
EndProcedure

If IsThread(thread)
  Debug "thread ON"
Else
  Debug "thread OFF"
EndIf

thread=CreateThread(@WorkingProgress(),100)

If IsThread(thread)
  Debug "thread ON"
Else
  Debug "thread OFF"
EndIf

Debug "terminé"
End