Page 1 sur 1

Propose idée tuto - Thread

Publié : jeu. 19/mai/2016 10:18
par Shadow
Salut,

Il serais vraiment très intéressant de faire un bon gros tuto
sur les thread car c'est galère je trouve avec PB :)

Re: Propose idée tuto - Thread

Publié : jeu. 19/mai/2016 10:46
par GG
+1, ça peut m'intéresser, je ne suis pas expert en la matière.

Re: Propose idée tuto - Thread

Publié : jeu. 19/mai/2016 10:57
par falsam
Un thread consiste à lancer une tache en arrière plan tout en permettant à l’application principale de fonctionner.

Exemple ce code sans thread.

Code : Tout sélectionner

Procedure MyProcedure()
  For n = 1 To 100000
    If IsGadget(0)      
      SetGadgetText(0, Str(n))
    EndIf
  Next 
EndProcedure

OpenWindow(0, 0, 0, 500, 500, "Thread")
StringGadget(0, 20, 20, 50, 20, "") 

MyProcedure()

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      End
  EndSelect 
ForEver
Freeze Assuré.

Re: Propose idée tuto - Thread

Publié : jeu. 19/mai/2016 11:02
par falsam
Alors comment faire ? En utilisant un thread. C'est à dire faire éxécuter la procédure MyProcedure() en arrière plan avec l'instruction CreateThread()

Code : Tout sélectionner

Procedure MyProcedure(*Value)
  For n = 1 To 100000
    If IsGadget(0)      
      SetGadgetText(0, Str(n))
    EndIf
  Next 
EndProcedure

OpenWindow(0, 0, 0, 500, 500, "Thread")
StringGadget(0, 20, 20, 50, 20, "") 

CreateThread(@MyProcedure(), 100)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      End
  EndSelect 
ForEver
Dans les paramétres de compilation, vous devez cocher la case Activer la gestion des Threads

■ CreateThread(@MyProcedure(), 100)
-Le premier paramètre est un pointeur sur la procédure MyProcedure().
-Le second paramètre est un numéro de Thread qui sera mémorisé dans la variable *Value de la procédure MyProcedure(). La valeur 100 est un exemple. Vous mettez ce que vous voulez.

Re: Propose idée tuto - Thread

Publié : jeu. 19/mai/2016 11:33
par falsam
Dans cet exemple un timer aurait suffit.

Code : Tout sélectionner

Procedure MyProcedure()
  Static n
  n + 1 
  SetGadgetText(0, Str(n))
EndProcedure

OpenWindow(0, 0, 0, 500, 500, "Un timer peut être plus simple")

StringGadget(0, 20, 20, 50, 20, "") 
AddWindowTimer(0, 1, 10)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Timer
      MyProcedure()
      
    Case #PB_Event_CloseWindow
      End
  EndSelect 
ForEver
■ AddWindowTimer(0, 1, 10) On ajoute le timer 1 de 10 ms à la fenêtre 0
■ Case #PB_Event_Timer l’événement est détectée et exécute la procédure MyProcedure().

En règle générale (ce n'est que mon opinion) préférer un timer, c'est plus simple à gérer et je crois plus stable.

Re: Propose idée tuto - Thread

Publié : jeu. 19/mai/2016 18:12
par cage
Bonjour a tous,

J'étais fan des Timers car venant de VB, les Timers étaient gérés en 'temps réel' et rien ne pouvait les bloquer.

Dans PB, j'ai vraiment été déçu car les Timers se bloquent dés que l'on fait une action.

Dans l'exemple donné avec le timer, cliquez juste sur la barre de titre et le compteur s’arrête.

Dés que j'ai découvert les Threads dans PB, j'ai remplacé toutes mes gestions Timer par des Threads.

Et comme le dit falsam
Dans les paramétres de compilation, vous devez cocher la case Activer la gestion des Threads
Je ne poste pas souvent, mais je lis tous les messages et j'y apprend beaucoup.
Merci a vous tous.
Gérard

Re: Propose idée tuto - Thread

Publié : jeu. 19/mai/2016 23:21
par Ar-S
@Cage,
Ce soucis de freeze n'a plus lieu via BindEvent(#PB_Event_Timer, @TimerEvent())

Code : Tout sélectionner

Global DureeSec = 10

Procedure TimerEvent()
  DureeSec -1
  SetGadgetText (1,"BOUGE LA FENETRE " + Str(DureeSec))
  PlaySound(10)
  
  If DureeSec <= 0
    SetGadgetText (1,"TERMINE")
    StopSound(10)
  EndIf
EndProcedure

If OpenWindow(0, 0, 0, 220, 121, "Minuteur", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget  (1, 1, 60, 218, 30, "BOUGE LA FENETRE ")
  AddWindowTimer(0,3,1000)
  BindEvent(#PB_Event_Timer, @TimerEvent()) ; Le BindEvent te permet de déplacer ta fenêtre tout en maintenant le compteur, 
EndIf

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
; En bonus on libère les ressources ;)
FreeSound(10)
UnbindEvent(#PB_Event_Timer, @TimerEvent())


Re: Propose idée tuto - Thread

Publié : sam. 21/mai/2016 15:13
par microdevweb
Petit conseille, placez un Delay dans la boucle d'un thread

Première exemple sans delay, le processeur est occupé à 25%

Code : Tout sélectionner

Procedure Teste(value)
    Repeat
        
    ForEver 
EndProcedure
OpenWindow(0,0,0,800,600,"teste",#PB_Window_SystemMenu)
CreateThread(@Teste(),1)
Repeat
    event=WaitWindowEvent()    
Until event=#PB_Event_CloseWindow
Deuxième exemple avec delay, le processeur est occupé à 0%

Code : Tout sélectionner

Procedure Teste(value)
    Repeat
        Delay(1)
    ForEver 
EndProcedure
OpenWindow(0,0,0,800,600,"teste",#PB_Window_SystemMenu)
CreateThread(@Teste(),1)
Repeat
    event=WaitWindowEvent()    
Until event=#PB_Event_CloseWindow

Re: Propose idée tuto - Thread

Publié : mer. 25/mai/2016 12:04
par falsam
microdevweb a écrit :Petit conseille, placez un Delay dans la boucle d'un thread
Le mien de conseil et de ne pas utiliser de Delay(). Delay() or not Delay(), il y a eu plusieurs débats sur ce sujet. Je ne ne reviendrais pas dessus.
microdevweb a écrit :Première exemple sans delay, le processeur est occupé à 25%
Une boucle Repeat ... ForEver sans aucune instruction à l'intérieur va pénaliser le processeur.

Reprenons ce premier exemple et plaçons un debug "passe" dans la boucle.

Code : Tout sélectionner

Procedure Teste(value)
  Repeat
    Debug "passe"   
  ForEver 
EndProcedure

OpenWindow(0,0,0,800,600,"teste",#PB_Window_SystemMenu)
CreateThread(@Teste(),1)

Repeat
  event=WaitWindowEvent(1)    
Until event=#PB_Event_CloseWindow
L'occupation processeur est de presque 0%. Ne pas oublier non plus de cocher la case Activer la gestion des threads dans les options de compilation.

Re: Propose idée tuto - Thread

Publié : mer. 25/mai/2016 12:26
par microdevweb
Et bien voici un autre teste

Sans Delay

Code : Tout sélectionner

Global X
Procedure Teste(value)
    Repeat
;         Delay(1)
      X+1
      If X>1000
          X=0
      EndIf
  ForEver 
EndProcedure
Image

Avec Delay

Code : Tout sélectionner

Global X
Procedure Teste(value)
    Repeat
        Delay(1)
      X+1
      If X>1000
          X=0
      EndIf
  ForEver 
EndProcedure

OpenWindow(0,0,0,800,600,"teste",#PB_Window_SystemMenu)
CreateThread(@Teste(),1)

Repeat
  event=WaitWindowEvent(1)    
Until event=#PB_Event_CloseWindow
Image

Alors faites comme vous le désiré, moi je place un Delay :wink: