So neu ist die Idee nicht. Ich wollte ihn aber von Grund auf selbst bauen.
Zunächst schien er zu laufen. Dann wollte ich aber sehen wieviel schneller er nun ist.
Nun bin ich an dem Punkt, dass ein neuer Thread sich manchmal nicht selbst auf Pause setzen kann, weil seine Adresse scheinbar noch null ist.
Ich weiß, das klingt blöde. Aber wenn man das Delay in Zeile 44 entfernt kommt spätestens beim 10. Programmaufruf in der IDE eine entsprechende Meldung.
Schlimmer noch : Als EXE läuft es gar nicht.[11:53:17] [ERROR] 002 Thread Benchmark.pb (Zeile: 45)
[11:53:17] [ERROR] Das angegebene 'Thread' ist null.
Hat irgend jemand eine Idee?
Code: Alles auswählen
CompilerIf #PB_Compiler_Thread
EnableExplicit
Define AnzahlThreads = 100
Define i, StartTimeA, StartTimeB, ElapsedTimeA, ElapsedTimeB
Global x
#New = 0
#Waiting = 1
#Working = 2
Structure ThreadStructure
Thread.i
Status.i
EndStructure
Global Dim ThreadInfo.ThreadStructure(AnzahlThreads) ; Basis ist 0 - Thread 0 ist für den Server reserviert
Macro Work(ThreadNumber)
Debug ThreadNumber
x+1
EndMacro
Macro StartThread(ThreadNumber)
;Debug " ThreadInfo("+Str(ThreadNumber)+")\Status = "+ ThreadInfo(ThreadNumber)\Status
If ThreadInfo(ThreadNumber)\Status = #Working
Debug "Thread " + Str(ThreadNumber) + " is already working"
; hier könnte ein Client eine angestoßene Verarbeitung stoppen bevor sie zu ende ist
Else
ResumeThread(ThreadInfo(ThreadNumber)\Thread) ;work
EndIf
EndMacro
Procedure ThreadA (ThreadNumber)
Repeat
If ThreadInfo(ThreadNumber)\Status = #Waiting
ThreadInfo(ThreadNumber)\Status = #Working
Work(ThreadNumber)
ThreadInfo(ThreadNumber)\Status = #Waiting
PauseThread(ThreadInfo(ThreadNumber)\Thread)
Else ; ThreadInfo(ThreadNumber)\Status = #New - " wurde gerade als Vorbereitung erzeugt - soll also im Moment noch nichts tun
Debug "Thread " + Str(ThreadNumber) + " wurde erzeugt"
ThreadInfo(ThreadNumber)\Status = #Waiting
Delay (10) ;- sonst kommt es hier vereinzelt zu "[ERROR] Das angegebene 'Thread' ist null."
PauseThread(ThreadInfo(ThreadNumber)\Thread)
EndIf
ForEver
EndProcedure
Procedure ThreadB (ThreadNumber)
Work(ThreadNumber)
EndProcedure
For i=1 To AnzahlThreads ; als Vorbereitung ThreadStructure füllen und Thread-Pool erzeugen
ThreadInfo(i)\Status = #New
ThreadInfo(i)\Thread = CreateThread(@ThreadA(), i)
Next i
Delay (100)
Debug "-------------"
Delay (900)
x=0
StartTimeA = ElapsedMilliseconds()
For i=1 To AnzahlThreads ; vorbereitete Threads arbeiten lassen
StartThread(i)
Next i
Repeat : Until x = AnzahlThreads
Delay (1000)
ElapsedTimeA = ElapsedMilliseconds()-StartTimeA-1000
x=0
StartTimeB = ElapsedMilliseconds()
For i=1 To AnzahlThreads ; Threads erzeugen und arbeiten lassen
CreateThread(@ThreadB(), i)
Next i
Repeat : Until x = AnzahlThreads
Delay (1000)
ElapsedTimeB = ElapsedMilliseconds()-StartTimeB-1000
MessageRequester("Information", Str(ElapsedTimeA)+" zu "+Str(ElapsedTimeB), #PB_MessageRequester_Ok)
Delay (100)
CompilerElse
Debug "Bitte 'Thread-sicheren Exekutable erstellen' in den Compiler-Optionen auswählen."
CompilerEndIf
Code: Alles auswählen
Repeat : Until ThreadInfo(ThreadNumber)\Thread
Code: Alles auswählen
Delay (10)