60% CPU-Auslastung trotz WaitWindowEvent()?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Delle
Beiträge: 1118
Registriert: 10.05.2005 22:48

60% CPU-Auslastung trotz WaitWindowEvent()?

Beitrag von Delle »

Hallo,

ich verwende diesen Code an einer bestimmten Stelle, er wartet meist eine zufällige Anzahl Minuten und prüft aber gleichzeitig ob der User evtl. abbricht:

Code: Alles auswählen

Repeat
                 
                 EventID = WaitWindowEvent()
                 
                 If EventID = #PB_Event_CloseWindow:End:EndIf
                 
                 If EventID=#PB_Event_Gadget And EventGadget()=#Suche
                 
                  SetGadgetText(#Suche, "Suche starten")
                  SetGadgetText(#Browser,"about:blank")
                  Break(3)
                  
                EndIf

Until (pausi + StartTime)<ElapsedMilliseconds()
Wieso verursacht das aber trotz WaitWindowEvent() fast 60% CPU-Auslastung?!

Danke!
PB 6.02 LTS + Win 11
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: 60% CPU-Auslastung trotz WaitWindowEvent()?

Beitrag von #NULL »

Leider ist nicht ersichtlicht was das Break 3 macht, da zu viel code fehlt. Aber auf jedenfall könnte dein SetGadgetText(#Suche.. erneut ein Event für genau dieses Gadget auslösen, womit du eine Art Endlosschleife erzeugst. Du solltest auch den EventType prüfen damit die Events die von SetGadgetText() verursacht werden nicht wieder ein SetGadgetText() auslösen.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Delle
Beiträge: 1118
Registriert: 10.05.2005 22:48

Re: 60% CPU-Auslastung trotz WaitWindowEvent()?

Beitrag von Delle »

Sieht grob so aus:

Code: Alles auswählen

Repeat 

EventID = WaitWindowEvent(50)

If EventID=#PB_Event_Gadget And EventGadget()=#Suche
  
   If GetGadgetText(#Suche)="Suche starten"
     SetGadgetText(#Suche, "Suche anhalten")
   EndIf
   
  Repeat
    
              ; ABLAUF START (Schleife)

              pausi.l = Random(1000*60*3,1000*60*1)
                          
              StartTime.q = ElapsedMilliseconds()
             
               Repeat
                 
                 EventID = WaitWindowEvent()
                 
                 If EventID = #PB_Event_CloseWindow:End:EndIf
                 
                 If EventID=#PB_Event_Gadget And EventGadget()=#Suche
                 
                  SetGadgetText(#Suche, "Suche starten")
                  SetGadgetText(#Browser,"about:blank")
                  Break(3)
                  
                EndIf
                
               Until (pausi + StartTime)<ElapsedMilliseconds()

               ; ABLAUF WEITER
                          
  ForEver
    
EndIf

;While WindowEvent():Wend

Until EventID = #PB_Event_CloseWindow
Läuft der WindowEvent in der Hauptschleife wohl auch noch!?
PB 6.02 LTS + Win 11
Benutzeravatar
Delle
Beiträge: 1118
Registriert: 10.05.2005 22:48

Re: 60% CPU-Auslastung trotz WaitWindowEvent()?

Beitrag von Delle »

Lassen wir mal die Interaktionen durch den User ganz weg, also weder Fensterschließen, noch irgendwelche Gadgets.

Das Programm soll beim Start sofort loslaufen, Abbruch durch Taskmanager.

Code: Alles auswählen

Repeat

If DatabaseQuery(#DB, "SELECT * FROM tabelle")
        
      While NextDatabaseRow(#DB)

           SetGadgetText(#Browser, GetDatabaseString(#DB, DatabaseColumnIndex(#DB, "url")))
           ; Warten bis Webseite in #Browser fertig geladen
           ; Diverse Aktionen durchführen
           ; Pause für 5 Minuten

      Wend

Forever
Bei Pause könnte ich einfach Delay(1000*60*50) nehmen, dann ist die CPU zumindest auf 0 aber das Programm ist als "inaktiv" markiert und gibt keine Rückmeldung (sieht halt aus als ob es "hängt").

Was/wo müssten da für WindowsEvents oben in den Code rein damit er nicht wieder die CPU durchknallt?
PB 6.02 LTS + Win 11
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: 60% CPU-Auslastung trotz WaitWindowEvent()?

Beitrag von #NULL »

Ist #Suche ein Button? Wie gesagt, auch auf EventType filtern

Code: Alles auswählen

If EventID=#PB_Event_Gadget And EventGadget()=#Suche And EventType() = #PB_EventType_LeftClick
     SetGadgetText(#Suche, "Suche starten")
<edit>
Du hast da oben zwei Event-Schleifen drin. Man kann sowas machen, will man aber lieber nicht.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
silbersurfer
Beiträge: 174
Registriert: 06.07.2014 12:21

Re: 60% CPU-Auslastung trotz WaitWindowEvent()?

Beitrag von silbersurfer »

Ohne jetzt genauers zu durchleuchten,
das SetGadgetText sollte nicht in der Wartescheife stehen, da dardurch auch ein Event ausgelöst wird.
was #NULL dir schon gesagt hatte
erneut ein Event für genau dieses Gadget auslösen, womit du eine Art Endlosschleife erzeugst
So ist es besser

Code: Alles auswählen

Repeat
If DatabaseQuery(#DB, "SELECT * FROM tabelle")
      SetGadgetText(#Browser, GetDatabaseString(#DB, DatabaseColumnIndex(#DB, "url"))) 
      While NextDatabaseRow(#DB)
           EventID = WaitWindowEvent()
           ; Warten bis Webseite in #Browser fertig geladen
           ; Diverse Aktionen durchführen
           ; Pause für 5 Minuten
      Wend
Forever
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander
Benutzeravatar
Delle
Beiträge: 1118
Registriert: 10.05.2005 22:48

Re: 60% CPU-Auslastung trotz WaitWindowEvent()?

Beitrag von Delle »

@silbersurfer:

Da setzt Du ja die URL ins Gadget, bevor überhaupt die DB-Schleife anfängt zu laufen ;)

Also mir würde wiegesagt auch eine Version OHNE jegliche Usereingaben via Gadget reichen, HAUPTSACHE die CPU läuft low.

Aktuell eben bei 60-70% und der Laptoplüfter dreht fast durch...
PB 6.02 LTS + Win 11
Benutzeravatar
mk-soft
Beiträge: 3700
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: 60% CPU-Auslastung trotz WaitWindowEvent()?

Beitrag von mk-soft »

Zeit intensive Bearbeitungen immer in einem Thread auslagern...

Um aus einen Thread die GUI zu aktualisieren, habe ich ja noch das Module ThreadToGUI.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Delle
Beiträge: 1118
Registriert: 10.05.2005 22:48

Re: 60% CPU-Auslastung trotz WaitWindowEvent()?

Beitrag von Delle »

mk-soft hat geschrieben:Zeit intensive Bearbeitungen immer in einem Thread auslagern...
Hatte ich ja ursprünglich gemacht, allerdings schmierte da ja immer das Programm ab. Threads und Gadgets halt...
mk-soft hat geschrieben:Um aus einen Thread die GUI zu aktualisieren, habe ich ja noch das Module ThreadToGUI.
Bläht den Code unnötig auf und schickt irgendwelche Daten Ping-Pong... der Thread muss ja auch wieder wissen wann z.B. das WebGadget fertig mit laden ist.
PB 6.02 LTS + Win 11
Benutzeravatar
mk-soft
Beiträge: 3700
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: 60% CPU-Auslastung trotz WaitWindowEvent()?

Beitrag von mk-soft »

Das problem ist, wann das Webgadget wirklich fertig ist mit den Laden der Webseite...

Nur mal schnell zusammengebastelt...

Code: Alles auswählen

;-TOP

CompilerIf #PB_Compiler_Thread = 0
  CompilerError "Compiler-Option Threadsafe aktivieren!"
CompilerEndIf

; Constant
Enumeration Window
  #Main
EndEnumeration

Enumeration Menu
  #Menu
EndEnumeration

Enumeration MenuItems
  #MenuStartThread
  #MenuExitApplication
EndEnumeration
  
Enumeration Gadgets
  #List
  #Browser
EndEnumeration

Enumeration Statusbar
  #Status
EndEnumeration

; -----------------------------------------------------------------------------

Enumeration CustomEvent #PB_Event_FirstCustomValue
  #MyEventLoadURL
EndEnumeration

Structure udtWork
  ThreadID.i
  Exit.i
  ; Daten
  List URL.s()
EndStructure

Structure udtSendData
  Status.i
  Semaphore.i
  URL.s
EndStructure

Procedure thWork(*data.udtWork)
  Protected SendData.udtSendData
  
  With *data
  
    SendData\Semaphore = CreateSemaphore()
    ForEach \URL()
      SendData\Status = 0
      SendData\URL = \URL()
      PostEvent(#MyEventLoadURL, 0, 0, 0, @SendData) 
      WaitSemaphore(SendData\Semaphore)
      ;TODO
      Delay(5000)
    Next
    
    FreeSemaphore(SendData\Semaphore)
  EndWith
  
EndProcedure

Global WorkData.udtWork

Procedure StartThread()
  
  With WorkData
    
    If IsThread(\ThreadID)
      ProcedureReturn 0
    EndIf
  
    AddElement(\URL()) : \URL() = "http://www.t-online.de"
    AddElement(\URL()) : \URL() = "about:blank"
    AddElement(\URL()) : \URL() = "http://www.heise.de"
    AddElement(\URL()) : \URL() = "http://www.chip.de"
    AddElement(\URL()) : \URL() = "http://www.purebasic.com"
    \ThreadID = CreateThread(@thWork(), WorkData)
    ProcedureReturn 1
  EndWith
  
EndProcedure

; -----------------------------------------------------------------------------

; Global Variable
Global ExitApplication

; Functions
Procedure UpdateWindow()
  
  Protected x, y, dx, dy, menu, status
  
  menu = MenuHeight()
  If IsStatusBar(#Status)
    status = StatusBarHeight(#Status)
  Else
    status = 0
  EndIf
  x = 0
  y = 0
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - menu - status
  ResizeGadget(#List, x, y, dx, dy)
  
EndProcedure

; Main
Procedure Main()
  
  Protected event, style, *MyEventData.udtSendData
  
  style = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
  dx = 800
  dy = 600
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, dx, dy, "Main", style)
    
    ; Enable Fullscreen
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS 
      Protected NewCollectionBehaviour
      NewCollectionBehaviour = CocoaMessage(0, WindowID(#Main), "collectionBehavior") | $80
      CocoaMessage(0, WindowID(#Main), "setCollectionBehavior:", NewCollectionBehaviour)
    CompilerEndIf
    
    ; Menu
    CreateMenu(#Menu, WindowID(#Main))
    MenuTitle("Ablage")
    MenuItem(#MenuStartThread, "Start Thread...")
    MenuBar()
    MenuItem(#MenuExitApplication, "Be&enden")
    ; Gadgets
    ListViewGadget(#List, 0, 0, dx, dy)
    WebGadget(#Browser, 0, 0, 0, 0, "about:blank")
    
    ; Statusbar
    CreateStatusBar(#Status, WindowID(#Main))
    AddStatusBarField(#PB_Ignore)
    
    UpdateWindow()
    
    ; Main Loop
    Repeat
      event = WaitWindowEvent()
      Select event
        Case #PB_Event_Menu
          Select EventMenu()
            CompilerIf #PB_Compiler_OS = #PB_OS_MacOS   
              Case #PB_Menu_About
                
              Case #PB_Menu_Preferences
                
              Case #PB_Menu_Quit
                ExitApplication = #True
                
            CompilerEndIf
              
            Case #MenuExitApplication
              ExitApplication = #True
              
            Case #MenuStartThread
              StartThread()
              
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #List
              
            Case #Browser
              Select EventType()
                Case #PB_EventType_DownloadStart
                  AddGadgetItem(#List, -1, "Download Start URL - " + GetGadgetText(#Browser))
                  
                Case #PB_EventType_DownloadEnd
                  AddGadgetItem(#List, -1, "Download End URL - " + GetGadgetText(#Browser))
                  If *MyEventData
                    *MyEventData\Status + 1
                    If *MyEventData\Status = 1
                      SignalSemaphore(*MyEventData\Semaphore)
                    EndIf
                  EndIf
                  
              EndSelect
              
          EndSelect
          
        Case #PB_Event_SizeWindow
          Select EventWindow()
            Case #Main
              UpdateWindow()
              
          EndSelect
          
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case #Main
              ExitApplication = #True
              
          EndSelect
          
        Case #MyEventLoadURL
          *MyEventData = EventData()
          AddGadgetItem(#List, -1, "Thread Request URL - " + *MyEventData\URL)
          SetGadgetText(#Browser, *MyEventData\URL)
          
      EndSelect
      
    Until ExitApplication
    
  EndIf
  
EndProcedure : Main()

End
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten