100% Cpu- Auslastung

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Deluxe0321
Beiträge: 336
Registriert: 19.05.2006 00:31
Kontaktdaten:

Beitrag von Deluxe0321 »

Seit der neuen Version von PB sind Timer auch direkt möglich (AddWindowTimer()), vondaher ist WindowEvent() wirklich nurnoch seltenst nötig.

Ich hab die Delay() Methode aber schon immer verwendet und auch wenn es falsch ist keine Probleme damit gehabt ;)


Grüße Marv
Ich habe keine Lösung, aber ich bewundere das Problem.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Wenns nur für Windows ist, würde ich den API-Timer bevorzugen, dann
wird die Routine auch beim verschieben des Fensters ausgeführt, hab den
Code mal daraufhin ergänzt, aber nicht soweit das er lauffähig wäre, weil
das hast Du ja auch nicht gemacht und ich mach hier nicht den Sklaven.

Code: Alles auswählen

Procedure TimerCallback(hWnd, uMsg, idEvent, dwTime)
  If idEvent = 2
    ; Clear the screen and draw our sprites
    ClearScreen(RGB(0, 0, 0))
    ClipSprite(0, 0, 0, x, x / 8)
    DisplaySprite(0, x, 100)
    DisplaySprite(0, x, x)
    DisplaySprite(0, 300 - x, x)
    DisplaySprite(0, playerX, playerY)
  
    FlipBuffers()       ; Inverse the buffers (the back become the front (visible)... and we can do the rendering on the back
  EndIf
EndProcedure

SetTimer_(WindowID(0), 2, 30, @TimerCallback())

Repeat
  Repeat
    ; Always process all the events to flush the queue at every frame
    Event = WaitWindowEvent()

    Select Event
      Case #PB_Event_CloseWindow
        Quit = 1

      Case #PB_Event_Gadget

        ; Do the normal application management here
    EndSelect

  Until Event = 0 ; Quit the event loop only when no more events are available



  ;<< hier würd ich mit einem Delay(1) die CPU-Last verringern

Until  Quit Or KeyboardPushed(#PB_Key_Escape)
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
HeX0R
Beiträge: 3040
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Beitrag von HeX0R »

ts-soft hat geschrieben:Wenns nur für Windows ist, würde ich den API-Timer bevorzugen, dann
wird die Routine auch beim verschieben des Fensters ausgeführt
Ich hab ja noch die Hoffnung, dass irgendwann nicht mehr alle Events beim Verschieben von Fenstern ins Nirvana geschickt werden.
Allerdings schwindet diese Hoffnung von Monat zu Monat mehr...
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

HeX0R hat geschrieben: Ich hab ja noch die Hoffnung, dass irgendwann nicht mehr alle Events beim Verschieben von Fenstern ins Nirvana geschickt werden.
Allerdings schwindet diese Hoffnung von Monat zu Monat mehr...
Hab mir entsprechendes beim Alphatest gewünscht, leider keine Reaktion.

So werde ich weiterhin die API-Version unter Windows nutzen, aber
zumindest hab ich jetzt auch unter Linux nen Timer, weil dort komm ich mit
der API garnicht klar, mach zu wenig damit :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Sven
Beiträge: 374
Registriert: 23.09.2004 12:01

Beitrag von Sven »

Danke TS, so mach ich das ja auch ;-) Schien mir nur für den Thread etwas - oversized... Aber die Methode von Kaeru ist auch nicht schlecht, fürn kleines Spiel oder so. Nur WaitWindowEvent mit Zeitangabe ist für sowas zu unzuverlässig.

Btw, bei anderen Windows-Versionen kann ich aber nicht davon ausgehen, dass die Timeslices zwischen 10 und 16 msec liegen, oder? Waren das bei Win 98 nicht 5 msec?
Olaf de Viesel
Beiträge: 9
Registriert: 31.08.2009 02:04

Beitrag von Olaf de Viesel »

So nun habe ich ein neues (altes) Problem mit der CPU- Auslastung:

Kurzes Vorwort:
Ich habe einen Countdown programmiert, der einfach Sekundenweise abläuft (was ein ganz normaler Countdown halt so macht ^^). Mit Benutzereingabe (extra Fenster wobei die CPU ebenfalls auf 100% läuft; ist jetzt auch erstmal uninterresant) und einen Start- und Stop- Button.

Nun wenn der Countdown durch den Benutzer eingegeben wurde und ich mit dem "Start"- Button den Timer starte habe ich zwar keine Auslastung mehr, jedoch kann ich den "Stop"- Button nicht mehr SOFORT drücken. Erst nach ca. 6 Sekunden stopt der Timer. Mithilfe einer Procedure/ Threat geht es auch irgendwie ne. Oder ich habe noch nicht richtig begriffen wie man einen Threat behandelt =)

Wie kann ich nun den Button drücken, welcher sofort reagiert, und die CPU- Auslastung dabei normal bleibt?

(Mithhilfe einer normalen Schleife ist das ganze Problem umgedreht... also: CPU hoch, aber kann alle Buttons drücken)

Vielen Dank im Vorraus
Benutzeravatar
jojo1541
Beiträge: 431
Registriert: 15.09.2007 17:12
Wohnort: Irgendwo im Nirgendwo

Beitrag von jojo1541 »

Wenn du deinen Countdown ohne Screen anzeigst, kannst du WaitWindowEvent() mit einem Timeout verwenden.
Ich verkaufe Rechtschreibfehler und jede menge GROßBUCHSTABEN. Alles unbegrenzt zu haben.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ohne Kot kann man da auch nur rumraten... /:->

also ich nehme mal stark an, dass du irgendwie eine in sich geschlossene schleife gebaut hast, um deinen countdown anzuzeigen.
natürlich reagier währenddessen der Button nicht, der reagiert immer nur, wenn der Programmablauf an einem
Event = (Wait)WindowEvent vorbei kommt, und du dann Event auch auswertest.

Code: Alles auswählen

EnableExplicit

Enumeration 
  #But_Start
  #But_Stop
  #Txt_Count
EndEnumeration

OpenWindow( 0, #PB_Ignore, 0, 300, 200, "Countdown")
  ButtonGadget( #But_Start,  16, 16, 80, 24, "Start" )
  ButtonGadget( #But_Stop ,  16, 48, 80, 24, "Stop" )
  TextGadget  ( #Txt_Count, 204, 16, 80, 80, "X", #PB_Text_Center|#PB_Text_Border )

Define.i EXIT = 0, COUNT = 0
Define.i Timer, DCounter
Define.i Event, EvGad

Timer = ElapsedMilliseconds() + 1000

Repeat
  Event = WaitWindowEvent(100)
  EvGad = EventGadget()
  Select Event
    Case #Null
      If COUNT
        If ElapsedMilliseconds() > Timer
          Timer + 1000
          DCounter -1
          SetGadgetText( #Txt_Count, Str(DCounter) )
          If DCounter = 0
            COUNT = 0
          EndIf
        EndIf
      EndIf
    Case #PB_Event_CloseWindow
      EXIT = 1
    Case #PB_Event_Gadget
      Select EvGad
        Case #But_Start
          Timer = ElapsedMilliseconds() + 1000
          COUNT = 1
          DCounter = 5
          SetGadgetText( #Txt_Count, Str(DCounter) )
        Case #But_Stop
          COUNT = 0
      EndSelect
  EndSelect
Until EXIT
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Olaf de Viesel
Beiträge: 9
Registriert: 31.08.2009 02:04

Beitrag von Olaf de Viesel »

Okay ich sehe ihr Programmiert alle mit SELECT -.- naja bin noch ein Anfänger...

Hier mein Code (gekürzt):

Code: Alles auswählen



If OpenWindow(0, 200, 200, 400, 200, "Shutdown Control", #PB_Window_TitleBar|#PB_Window_SystemMenu )

  If CreateGadgetList(WindowID(0))
  TextGadget    (5,  10, 28, 200, 15,"Shutdown Status:")
  TextGadget    (6,  10, 40, 200, 8,"--------------------------------")
  ButtonGadget  (1, 260, 25, 120 , 24, "Neuer Countdown")
  ButtonGadget  (2, 260, 120, 120 , 24, "Info")
  ButtonGadget  (9, 260, 160, 120 , 24, "Exit")
  ButtonGadget  (3, 20, 160, 80  , 24, "Start")
  ButtonGadget  (4, 120, 160, 80 , 24, "Stop")
  TextGadget    (7,  10, 50, 200, 100,"", #PB_Text_Border) 
  TextGadget    (8,  150, 10, 200, 15,"") 
  ;CheckBoxGadget(0, 290,  90, 250, 20, "Neustarten")
  OptionGadget  (20, 270, 60, 90, 20, "Neustarten")
  OptionGadget  (21, 270, 80, 90, 20, "Herunterfahren")
  SetGadgetState(21, 1)

  EndIf

EndIf
 
 (...)

;// Start Main- Programm

 Repeat  
    EventID = WaitWindowEvent() 
       If EventID = #PB_Event_Gadget
       GadgetNummer = EventGadget()
       
;// Exit  

          If GadgetNummer = 9
          End
          EndIf


;// Info  

 (...)


;// Start

          If GadgetNummer = 3
           If Start.l = 1
             Repeat
             StartTime = ElapsedMilliseconds()
            
               Repeat
               Time.l = ElapsedMilliseconds()-StartTime 
               EventID3 = WindowEvent()
               GadgetNummer2 = EventGadget()
              
               ;SetGadgetText (7, Str(Time))    // DebugInfo
               Until Time.l >= 1000
                          
               Sek.l = Sek.l -1
               SetGadgetText (7, "            Timer gestartet...(H : M : S)" + Chr(10) + Chr(10) + Chr(10) + "                            " + Str(Hou.l) + ":" + Str(Min.l) + ":" + (Str(Sek.l)))
 
               If Sek.l <= 0
               Min.l = Min.l - 1
               Sek.l = Sek.l + 60

               If Min.l < 0
                 Min.l = 0
                 Hou.l = Hou.l - 1

                  If Hou.l <> 0
                 ;Hou.l = Hou.l -1
                  Min.l = Min.l + 59
                  EndIf

                  If Hou.l <= 0
                  Hou.l = 0
                  Min.l = 0
                  Sek.l = 0
                  EndIf

               EndIf

              EndIf
             
             Until Sek.l = 0 Or GadgetNummer2 = 4

            EndIf

             If GadgetNummer2 = 4
             SetGadgetText (7, "            Timer gestartet...(H : M : S)" + Chr(10) + Chr(10) + Chr(10) + "                            " + Str(Hou.l) + ":" + Str(Min.l) + ":" + (Str(Sek.l)) + Chr(10) + Chr(10) + "Timer gestoppt! Zum Fortsetzten 'Start' drücken!")
             EndIf

             
;// Timer beendet

             If Sek.l = 0
             State = GetGadgetState(20) 

             If State = 1
             ;RunProgram("C:\Windows\System32\shutdown.exe","-r -t 10 -f","System wird in 10 Sekunden neu gestartet!") 
             Else
             ;RunProgram("C:\Windows\System32\shutdown.exe","-s -t 10 -f","System wird in 10 Sekunden Heruntergefahren!") 
             EndIf
             
             EndIf
         
          
          EndIf


;// Neuer Countdown

          If GadgetNummer = 1
             
             If OpenWindow(1, 200, 200, 230, 200, "Shutdown Control", #PB_Window_TitleBar|#PB_Window_SystemMenu )

                If CreateGadgetList(WindowID(1))
                TextGadget    (10,  10, 30, 200, 15,"Timer:")
                TextGadget    (11,  10, 40, 200, 10,"--------------------------------")
                ButtonGadget  (12, 80, 160, 80  , 24, "Speichern")
                StringGadget  (14, 30,  60, 40, 20, "")
                StringGadget  (15, 90,  60, 40, 20, "")
                StringGadget  (16, 150,  60, 40, 20, "")

                EndIf
                    
                Eingabe:
                Repeat
                
                EventID = WindowEvent()
                GadgetNummer = EventGadget()
                
               
                If GadgetNummer = 12
                 Sekunden$ = GetGadgetText (16)
                Sek.l = Val(Sekunden$)
                
                Minuten$ = GetGadgetText (15)
                Min.l = Val(Minuten$)
                
                Hour$ = GetGadgetText (14)
                Hou.l = Val(Hour$)
                
                 If Sek.l < 0
                 
                 MessageRequester ("ERROR" , "Falsche Eingabe! Überprüfung erforderlich!")
                 SetGadgetText (16," ")
                 Fehler = 1
                 EndIf
  
  
                 If Min.l < 0
                 Min.l = 0
                 MessageRequester ("ERROR" , "Falsche Eingabe! Überprüfung erforderlich!")
                 SetGadgetText (15," ")
                 Fehler = 1
                 EndIf
  
                 If Hou.l < 0
                 Hou.l = 0
                 MessageRequester ("ERROR" , "Falsche Eingabe! Überprüfung erforderlich!")
                 SetGadgetText (14," ")
                 Fehler = 1
                 EndIf
                 
                If Fehler = 1
                Fehler = 0
                Goto Eingabe:
                Else
                EventID = 1
                EndIf
                
                EndIf
                
                If EventID = #PB_Event_CloseWindow
                EventID = 1
                
                EndIf

                Until EventID = 1
                
                If Sek.l >= 60
                Repeat
                Min.l = Min.l + 1
                Sek.l = Sek.l - 60
                Until Sek.l <= 59
                EndIf 

                If Min.l >= 60
                Repeat
                Hou.l = Hou.l + 1
                Min.l = Min.l - 60
                Until Min.l <= 59
                EndIf
                
                SetGadgetText (7, "Timer initialisiert... " + Chr(10) + "Timer gestellt auf: " + Str(Hou.l) + ":" + Str(Min.l) + ":" + Str(Sek.l))
                Start.l = 1
                CloseWindow(1)
                ;    
             EndIf  
          
          EndIf
          
       EndIf


  Until EventID = #PB_Event_CloseWindow  
;EndIf

[/code]
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

> Hier mein Code (gekürzt):
Naja, aber Ausführbar sollte er schon sein, dann hätte ich mir vielleicht die
Mühe gemacht aus dem ganzen einen sinnvollen und vor allem strukturierten
Code zu machen.

Mit Deinen 3 (waren das jetzt 3?) Schleifen, wo in einer evtl. nicht verloren
gegangene Ereignisse auftreten, so kann das nun nichts werden. Mein
Beispiel mit TimerProcedure hab ich ja bereits gepostet, mußte nur anpassen.

Deinen Pseudocode in diesem Stil werde ich nicht überarbeiten, aber
vielleicht bietest Du uns ja noch eine bessere Version, so schwer kanns doch
garnicht sein, oder es findest sich ein anderer.

Gruß

Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten