Aktuelle Zeit: 23.08.2019 15:25

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Mini Thread Control
BeitragVerfasst: 13.07.2019 11:45 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Habe zwar schon einige Beispiele geschrieben.

Hier aber mit möglichst wendig Code.

Update v1.03
- StopThread gibt jetzt immer den Semaphore frei

Update v1.04
- StopThread optimiert

Update v1.05
- FreeThread hinzugefügt

Update v1.06
- Code bereinigt
Code:
;-TOP

;- Begin Mini Thread Control

;  by mk-soft, Version 1.06, 20.07.2019

CompilerIf Not #PB_Compiler_Thread
  CompilerError "Use Compiler-Option ThreadSafe!"
CompilerEndIf

Structure udtThreadControl
  ThreadID.i
  UserID.i
  Signal.i
  Pause.i
  Exit.i
EndStructure

Procedure StartThread(*Data.udtThreadControl, *Procedure) ; ThreadID
  If Not IsThread(*Data\ThreadID)
    *Data\ThreadID = CreateThread(*Procedure, *Data)
  EndIf
  ProcedureReturn *Data\ThreadID
EndProcedure

Procedure StopThread(*Data.udtThreadControl, Wait = 1000) ; Void
  If IsThread(*Data\ThreadID)
    *Data\Exit = #True
    If *Data\Pause
      *Data\Pause = #False
      SignalSemaphore(*Data\Signal)
    EndIf
    If WaitThread(*Data\ThreadID, Wait) = 0
      KillThread(*Data\ThreadID)
    EndIf
    *Data\ThreadID = 0
    *Data\Pause = #False
    *Data\Exit = #False
  EndIf
  If *Data\Signal
    FreeSemaphore(*Data\Signal)
    *Data\Signal = 0
  EndIf
EndProcedure

Procedure FreeThread(*Data.udtThreadControl, Stop = #True, Wait = 1000) ; True or False
  If IsThread(*Data\ThreadID)
    If Stop
      StopThread(*Data, Wait)
      FreeStructure(*Data)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  Else
    If *Data\Signal
      FreeSemaphore(*Data\Signal)
    EndIf
    FreeStructure(*Data)
    ProcedureReturn #True
  EndIf
EndProcedure

Procedure ThreadPause(*Data.udtThreadControl) ; Void
  If IsThread(*Data\ThreadID)
    If Not *Data\Signal
      *Data\Signal = CreateSemaphore()
    EndIf
    If Not *Data\Pause
      *Data\Pause = #True
    EndIf
  EndIf
EndProcedure

Procedure ThreadResume(*Data.udtThreadControl) ; Void
  If IsThread(*Data\ThreadID)
    If *Data\Pause
      *Data\Pause = #False
      SignalSemaphore(*Data\Signal)
    EndIf
  EndIf
EndProcedure

;- End Mini Thread Control

; ****

CompilerIf #PB_Compiler_IsMainFile
 
  ;- Example
 
  Enumeration #PB_Event_FirstCustomValue
    #MyEvent_ThreadFinished
  EndEnumeration
 
  Enumeration Gadget
    #ButtonStart1
    #ButtonStart2
    #ButtonPauseResume1
    #ButtonPauseResume2
    #ButtonStop1
    #ButtonStop2
  EndEnumeration
 
  Structure udtFileData
    Name.s
    Result.s
  EndStructure
 
  ; Extends always own data structure with structure from thread control
  Structure udtThreadData Extends udtThreadControl
    ; Data
    Window.i
    Event.i
    List Files.udtFileData()
  EndStructure
 
  Procedure MyThread(*Data.udtThreadData)
    Protected c
   
    With *Data
      Debug "Init Thread " + \UserID
      ;TODO
      Delay(500)
      Debug "Start Thread " + \UserID
      ;TODO
      ForEach \Files()
        ; 1. Query on thread pause
        If \Pause
          Debug "Pause Thread " + \UserID
          WaitSemaphore(\Signal)
          Debug "Resume Thread " + \UserID
        EndIf
        ; 2. Query on thread cancel
        If \Exit
          Break
        EndIf
        ;TODO
        Debug "Busy Thread " + \UserID + ": File " + \Files()\Name
        Delay(500)
        \Files()\Result = "Ready."
      Next
      If \Exit
        ;TODO Thread Cancel
        Debug "Cancel Thread " + \UserID
      Else
        ;TODO Thread Finished
        Debug "Shutdown Thread " + \UserID
        PostEvent(\Event, \Window, 0, 0, *Data) ; <- EventData = Pointer to ThreadData
      EndIf
      Debug "Exit Thread " + \UserID
      ; 3. Clear ThreadID
      \ThreadID = 0
    EndWith
  EndProcedure
 
  ; Create Data always with AllocateStructure 
  Global *th1.udtThreadData = AllocateStructure(udtThreadData)
  *th1\UserID = 1
  *th1\Window = 1
  *th1\Event = #MyEvent_ThreadFinished
  For i = 10 To 30
    AddElement(*th1\Files())
    *th1\Files()\Name = "Data_" + i
  Next
 
  Global *th2.udtThreadData = AllocateStructure(udtThreadData)
  *th2\UserID = 2
  *th2\Window = 1
  *th2\Event = #MyEvent_ThreadFinished
  For i = 31 To 60
    AddElement(*th2\Files())
    *th2\Files()\Name = "Data_" + i
  Next
 
  ; Output Data
  Procedure Output(*Data.udtThreadData)
    Debug "Thread Finished UserID " + *Data\UserID
    MessageRequester("Thread Message", "Thread Finished UserID " + *Data\UserID)
    ForEach *Data\Files()
      Debug *Data\Files()\Name + " - Result " + *Data\Files()\Result
    Next
  EndProcedure
 
  If OpenWindow(1, 0, 0, 222, 250, "Mini Thread Control", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ButtonGadget(#ButtonStart1, 10, 10, 200, 30, "Start 1")
    ButtonGadget(#ButtonStart2, 10, 50, 200, 30, "Start 2")
    ButtonGadget(#ButtonPauseResume1, 10, 90, 200, 30, "Pause 1")
    ButtonGadget(#ButtonPauseResume2, 10, 130, 200, 30, "Pause 2")
    ButtonGadget(#ButtonStop1, 10, 170, 200, 30, "Stop 1")
    ButtonGadget(#ButtonStop2, 10, 210, 200, 30, "Stop 2")
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          FreeThread(*th1)
          FreeThread(*th2)
          Break
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #ButtonStart1
              StartThread(*th1, @MyThread())
            Case #ButtonStart2
              StartThread(*th2, @MyThread())
            Case #ButtonPauseResume1
              If IsThread(*th1\ThreadID)
                If Not *th1\Pause
                  ThreadPause(*th1)
                  SetGadgetText(#ButtonPauseResume1, "Resume 1")
                Else
                  ThreadResume(*th1)
                  SetGadgetText(#ButtonPauseResume1, "Pause 1")
                EndIf
              EndIf
            Case #ButtonPauseResume2
              If IsThread(*th2\ThreadID)
                If Not *th2\Pause
                  ThreadPause(*th2)
                  SetGadgetText(#ButtonPauseResume2, "Resume 2")
                Else
                  ThreadResume(*th2)
                  SetGadgetText(#ButtonPauseResume2, "Pause 2")
                EndIf
              EndIf
            Case #ButtonStop1
              StopThread(*th1)
              SetGadgetText(#ButtonPauseResume1, "Pause 1")
            Case #ButtonStop2
              StopThread(*th2)
              SetGadgetText(#ButtonPauseResume2, "Pause 2")
          EndSelect
         
        Case #MyEvent_ThreadFinished
          Output(EventData())
         
      EndSelect
    ForEver
  EndIf
 
CompilerEndIf

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Zuletzt geändert von mk-soft am 20.07.2019 13:34, insgesamt 4-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Mini Thread Control
BeitragVerfasst: 13.07.2019 22:06 
Offline
Benutzeravatar

Registriert: 10.09.2004 09:59
Das hier:
Code:
While IsThread(*Data\ThreadID)
  If ElapsedMilliseconds() - time > Wait
    KillThread(*Data\ThreadID)
    Break
  EndIf
  Delay(10)
Wend

Lässt sich einfacher so machen:
Code:
If WaitThread(*Data\ThreadID, Wait) = 0
  KillThread(*Data\ThreadID)
EndIf

_________________
Link tot?
Ändere h3x0r.ath.cx in hex0rs.coderbu.de und alles wird gut.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Mini Thread Control
BeitragVerfasst: 13.07.2019 23:25 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Update v1.04
- StopThread optimiert

Danke HeXOR,

ab und zumal in die Hilfe schauen kann nicht schaden :roll:
Auch wenn man schon lange dabei ist...

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Mini Thread Control
BeitragVerfasst: 14.07.2019 15:20 
Offline
Benutzeravatar

Registriert: 04.02.2005 15:40
Wohnort: Kaufbeuren
Mini-Thread Control als Modul:

Download: ThreadControlModule.pbi

_________________
Download der PureBasic-Module (GitHub)

Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Mini Thread Control
BeitragVerfasst: 14.07.2019 22:44 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Update v1.05
- FreeThread hinzugefügt

Stoppt bei bedarf den laufenden Thread und gibt den Speicher frei. Der Speicher muss mit AllocateStructure anlegt sein.

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye