Da muss ich aber ausholen ...
Ein Thread macht normalerweise irgendeine Tätigkeit im Hintergrund und, wenn er fertig ist, dann macht er Schluss.
Nun will man ja sehen, ob der Thread läuft oder man ist an Zwischenergebnissen interessiert. Also schaut man in Variablen hinein, die im Thread laufend verändert werden. Man kann auch über solche Variablen ein echtes Handshaking aufbauen. ZB. nur, wenn im GUI der Anwendung eine Variable ausgelesen und zu Null gesetzt worden ist, schreibt der Thread wieder etwas hinein. Inzwischen sammelt er seine Ergebnisse in lokalen Variablen.
Auf diesem Wege (es gibt auch andere) kann man eine sichere Threadkonstruktion aufbauen.
Strings darf man nicht verwenden, besonders nicht in HT-Systemen, denn PB verwaltet alle Strings in einem Pool und nicht für jeden Prozessor getrennt. Aber nullterminierte Byte-Array tun es ja auch.
Der Debugger ist überhaupt nicht Thread-fest, egal was man anstellt.
Da muss man sich im GUI für die Testphase einfach entsprechende Ausgabemöglichkeiten in Gadgets schaffen, wie es im Beispiel gezeigt ist.
@junky : nun zu Deiner speziellen Frage. Wenn "draußen" nichts von den Ergebnissen des Thread angezeigt werden soll, dann kann dieser natürlich frei und so schnell es geht laufen. Wenn kein Delay eingebaut ist, dann regelt das OS eben per Zeitscheiben die Verteilung der CPU-Zeit an die Prozesse. Das Delay() ist eben ein probates Mittel, die beiden quasi-zeitgleich ablaufenden Programmteile aufeinander abzustimmen.
@Team100 : Wir haben eine größere Anwendung in Arbeit, die, nachdem wir alle diese Dinge herausgefunden und beachtet haben, in dieser Hinsicht stabil läuft. Unsere Betatester (weltweit) haben uns wenigstens bisher keinerlei Probleme dazu auf den Tisch gepackt.
Hier noch ein bischen Code zum spielen. Er läuft nur als Exe, ist aber schon fast ein neuer Benchmark. Bei mir (P4 3.0HT) liegt die beobachtete minimale Zeit pro Run bei 7.360 Sekunden. Ein Run ist eine Long rauf und runter, also > 50 Mio Durchläufe pro Sekunde.
Das Delay(0) hat bei meinem System einen beruhigenden Effekt und drückt die Minimalzeit! Win ist nun mal kein Echtzeit-BS !
Durch Erzeugen von CPU-Last kann man schön sehen, wie sich das Verhalten der Thread-Konstruktion ändert.
Code: Alles auswählen
; Thread-Test 2 by jear 0500301
Global HVar.l, runs.l, dt.f
DefType.f dtmax , dtmin
Procedure.l Thread()
Protected ix.l, t0.l
t0 = GetTickCount_()
Repeat
ix + 1
If ix = 0 : runs + 1 : dt = (GetTickCount_() - t0)/1000 : t0 = GetTickCount_() : EndIf
If HVar = 0 : HVar = ix : Delay(0): EndIf
ForEver
EndProcedure
If OpenWindow(0, 300, 300, 200, 200, #PB_Window_SystemMenu, "Thread-Test")
If CreateGadgetList(WindowID())
TextGadget(1, 20, 20, 50, 12, "WinEvent")
TextGadget(2, 20, 40, 50, 12, "Runs")
TextGadget(3, 20, 60, 50, 12, "ThreadVar")
TextGadget(4, 20, 80, 50, 12, "TDiff (s)")
TextGadget(5, 20, 100, 50, 12, "TDiff min")
TextGadget(6, 20, 120, 50, 12, "TDiff max")
TextGadget(7, 90, 20, 80, 12, "0",#PB_Text_Right)
TextGadget(8, 90, 40, 80, 12, "0",#PB_Text_Right)
TextGadget(9, 90, 60, 80, 12, "0",#PB_Text_Right)
TextGadget(10, 90, 80, 80, 12, "0.000",#PB_Text_Right)
TextGadget(11, 90, 100, 80, 12, "0.000",#PB_Text_Right)
TextGadget(12, 90, 120, 80, 12, "0.000",#PB_Text_Right)
CloseGadgetList()
EndIf
dtmin = 999.000
CreateThread(@Thread(), 0)
SetTimer_(WindowID(),1,100,0)
Repeat
EventID.l = WaitWindowEvent()
SetGadgetText(7, Str(EventID))
If EventID = #WM_TIMER
SetGadgetText(8, Str(runs))
SetGadgetText(9, Str(HVar))
SetGadgetText(10, StrF(dt,3))
If dt > 0.0 And dt < dtmin : dtmin = dt : SetGadgetText(11, StrF(dtmin,3)) : EndIf
If dt > dtmax : dtmax = dt : SetGadgetText(12, StrF(dtmax,3)) : EndIf
HVar = 0 ; Flag-Funktion
SetTimer_(WindowID(),1,100,0)
ElseIf EventID = #PB_Event_CloseWindow
Quit = 1
EndIf
Until Quit = 1
EndIf
KillTimer_(WindowID(),1)
End