Seite 1 von 2

Thread - Tester gesucht

Verfasst: 28.02.2005 20:43
von junky
Nabend,

ich hab Probleme mit dem folgenden Stückchen Code (is nur ein Testcode, nachdem in meinem Projekt garnix mehr laufen wollte und ich mich gefragt hab, WARUM?)

Code: Alles auswählen

Procedure.l Thread()
  Protected ThreadVar.l
  Repeat
    ThreadVar+1
    Debug(ThreadVar)
  ForEver
EndProcedure

CreateThread(@Thread(), 0)



If OpenWindow(0, 300, 300, 300, 150, #PB_Window_SystemMenu, "Thread-Test")
  Repeat
    EventID.l = WindowEvent()
    
    If EventID = #PB_Event_CloseWindow
      Quit = 1
    EndIf
    Delay(1)
  Until Quit = 1
EndIf
End
am besten wär natürlich, wenn mir jetz irgendwer ins Gesicht springen könnte und sagen würde, DA is der Fehler

aber es würde mir auch schon reichen, wenn ein paar von euch, den Code einfach ma MIT EINGESCHALTETEN DEBUGGER testen würden und mir dann posten, wie euer Ergebnis is. Bei mir verreckt das Programm bei durchschnittlich 70.000-200.000 ...
Achso, falls jetz welche meinen "Da fehlt doch ein Delay in der Thread-Prozedur" - ich benötige die Rechenpower und kann mir so einen Delay nicht leisten :(

Die Frage lautet also konkret: Wieso verreckt er ?

Verfasst: 28.02.2005 21:56
von Laurin
Der Fehler muss irgendwo in deinem System liegen. Ich hab den Code bis 370.000 laufen lassen. Danach habe ich ihn abgebrochen, weil keine Fehler auftraten.


Greetz Laurin

Edit:
Ich hab deinen Code mal etwas abgeändert, damit das Testen nicht so lange dauert:

Code: Alles auswählen

Procedure.l Thread()
  Protected ThreadVar.l
  Repeat
    For i = 1 To 1000
      ThreadVar+1
    Next
    Debug(ThreadVar)
  ForEver
EndProcedure

CreateThread(@Thread(), 0)

If OpenWindow(0, 300, 300, 300, 150, #PB_Window_SystemMenu, "Thread-Test")
  Repeat
    EventID.l = WindowEvent()
    
    If EventID = #PB_Event_CloseWindow
      Quit = 1
    EndIf
    Delay(1)
  Until Quit = 1
EndIf
End 
Und nun tritt plötzlich der Fehler auf, dass das Programm einfach stehen bleibt.

Durchläufe bis Programmstillstand:
1.489.000
3.069.000
3.475.000
308.000
1.030.000
840.000
1.441.000
1.735.000

Verfasst: 28.02.2005 22:04
von junky
hm - sehr seltsam, aber trotzdem schonmal danke ...
die PB-Version wäre jetz noch wichtig

Könnten bitte nochmal ein paar andere den Code durchtesten - will dann jetzt sichergehen, dass es an meinem System liegt. Dauert echt nur ein paar Sekunden und ist wirklich wichtig für mich...

Edit:
oha - ok, danke nochma - also liegts doch nit an meinem System ?! - Hat wer ne Idee, wasses sein könnte ?

Verfasst: 28.02.2005 22:45
von nco2k
bei mir bleibt es auch stehen, aber immer unterschiedlich. im ersten code, hörte es sogar einmal beim 49. durchlauf auf. :freak:

pb3.93b3

c ya,
nco2k

Verfasst: 28.02.2005 22:47
von Team100
Ich bin kein Thread-Spezialist aber das Thema interessiert mich.

Lies mal hier:
http://forums.purebasic.com/english/vie ... hp?t=13712

Das Aufrufen des Debuggers bedeutet wohl Strings im Thread zu
verwenden und das darf nicht sein (siehe Hilfe)

Es wäre interessant, ob der Thread auch ohne Debugger abstürzt.

Zum Thema Threadsicherheit ist auch dieser Beitrag interessant
http://forums.purebasic.com/english/vie ... php?t=9624

Ich hoffe, daß jemand eine Antwort findet, wie gesagt, das Thema ist
interessant .... :) , leider kann ich hier nicht helfen.

/edit Die Links stimmen, wenn die englische Seite nicht wieder mal
abgestürzt ist wie gerade jetzt ....... /:->

Cu von Team100

Verfasst: 28.02.2005 22:52
von nco2k
@Team100
jo das könnte sein. :cry:

wenn man das debug durch beep_() ersetzt, dann scheint es zu gehen. habs aber nicht sehr lang laufen lassen, von daher "angaben ohne gewähr".

c ya,
nco2k

Verfasst: 28.02.2005 23:23
von junky
hm, jetz is keine Stringfunktion mehr im Thread - und funzt dennoch nicht
Was ich komisch finde, ruft des einmal MIT und einmal OHNE Debugger auf...

Code: Alles auswählen

Global ThreadVar.l

Procedure.l Thread()
  Repeat
    ThreadVar+1
  ForEver
EndProcedure

CreateThread(@Thread(), 0)

If OpenWindow(0, 300, 300, 300, 150, #PB_Window_SystemMenu, "Thread-Test")

  CreateGadgetList(WindowID())
  StringGadget(0, 50, 50, 100, 20, "")
    
  Repeat
    EventID.l = WindowEvent()
    
    If EventID = #PB_Event_CloseWindow
      Quit = 1
    EndIf
    SetGadgetText(0, Str(ThreadVar))
    ;Debug(Str(ThreadVar))
    Delay(1)
  Until Quit = 1
EndIf
End
PS: bekommt man eigentlich einen Thread irgendwie String-sicher ? Vllt auch noch ohne Semaphore ?

Keine Strings, kein Debugger, Delay(1) im Thread !

Verfasst: 28.02.2005 23:28
von jear
So läuft es. Auch als Exe.

Code: Alles auswählen

; Thread-Test
Global HVar.l

Procedure.l Thread() 
  Repeat 
    While HVar < 1000 : Delay(1) : HVar + 1 : Wend 
    HVar = 0
  ForEver 
EndProcedure  

If OpenWindow(0, 300, 300, 150, 150, #PB_Window_SystemMenu, "Thread-Test") 
  If CreateGadgetList(WindowID())
    TextGadget(1, 20, 20, 50, 12, "WinEvent")
    TextGadget(2, 20, 60, 50, 12, "ThreadVar")
    TextGadget(3, 80, 20, 50, 12, "0",#PB_Text_Right)
    TextGadget(4, 80, 60, 50, 12, "0",#PB_Text_Right)
    ButtonGadget(5, 40, 100, 70, 20, "reset")
    ;CloseGadgetList()
  EndIf  
  CreateThread(@Thread(), 0)
  SetTimer_(WindowID(),1,10,0) 
  Repeat 
    EventID.l = WaitWindowEvent() 
    SetGadgetText(3, Str(EventID))
    If EventID = #WM_TIMER
      SetGadgetText(4, Str(HVar))
      SetTimer_(WindowID(),1,10,0)
    ElseIf EventID = #PB_EventGadget 
      If EventGadgetID() = 5
        HVar = 0
      EndIf  
    ElseIf EventID = #PB_Event_CloseWindow 
      Quit = 1 
    EndIf  
  Until Quit = 1  
EndIf 
KillTimer_(WindowID(),1)
End 

Verfasst: 28.02.2005 23:36
von junky
@jear - fein, klappt wirklich - und jetz bitte nochmal die ThreadVariable so schnell wie in meinem Beispiel inkrementieren lassen ;)
Achso, falls jetz welche meinen "Da fehlt doch ein Delay in der Thread-Prozedur" - ich benötige die Rechenpower und kann mir so einen Delay nicht leisten :(

Verfasst: 28.02.2005 23:53
von jear
... und jetz bitte nochmal die ThreadVariable so schnell wie in meinem Beispiel inkrementieren lassen
Das Delay gibt die Kontrolle an das OS zurück, damit die "Anderen" auch mal dran kommen.
Das Delay liegt in meinem Beispiel in der Schleife um einen venünftigen Takt mit dem Timer in der Hauptschleife zu erzielen.
Es nutzt ja nichts, wenn Du in der Hauptschleife nur alle Sekunde nachschaust. Dann hat der Thread schon 3 Überläufe gehabt, wenn er frei läuft und Du hast kein "sinnvolles" Zählergebnis.
Es kommt also darauf an, was du da auf welche Art miteinander ticken lassen willst. Du musst also in Deiner Anwendung die richtige Abstimmung zwischen GUI und dem im Hintergrund werkelndem Thread finden.