aktuell wird bei einem Programm alles nacheinander in einer Schleife abgearbeitet und anschließend die gesammelten Ergebnisse mittels ausgabe$ ausgegeben:
Procedure Verarbeitung(ID usw.)
load$=Images()\ImagePath.s
; Verarbeitung
FreeImage(Images()\ImageID)
DeleteElement(Images())
; ProcedureReturn ??? oder ausgabe$+bildergebnis$ ?
EndProcedure
ForEach Images()
; jeweils einen Thread für Prozedure "Verarbeitung" starten
Next
; warten bis alle Threads "fertig" sind?!?
Debug ausgabe$
Wie generiere ich aber "dynamische" Threads und wie erfahre ich ob alles Threads fertig sind?
Threads zu erstellen dauert vom Prinzip her recht lange.
Stattdessen würde ich lieber am Anfang je nach anzahl der Kerne, 2-8 Threads erstellen.
Das heißt, die Verarbeitungsschleife laufen schon alle im "Ruhemodus" und warten auf eine Aufgabe.
Danach verteilst du zB deine 100 Aufgaben gleichmäßig auf die Threads, in denen sie dann wieder "normal" nacheinander abgearbeitet werden.
Noch ein paar Hinweise:
ProcedureReturn gibt in einem Thread nicht!
Stattdessen solltest du zB mit Semaphore um die Fertigstellung einer Aufgabe "anzuzeigen".
Falls die Arbeitsschritte aufeinander aufbauen, also abhängig von einander sind, kannst du es nicht parallelisieren.
Und wenn sie nicht abhängig sind, kann jeder sein Ergebnis selbst im Endergebnis eintragen.
Und noch was. Da du mit Bildern arbeiten willst, darfst du nicht 'StartDrawing()' nutzen, denn das ist nicht threadfähig. Du kannst höchsten den 'DrawingBuffer()' verwenden.
Das Problem ist folgendes: Angenommen Thread 1 führt 'StartDrawing()' aus und direkt danach macht Thread 2 das selbe, dann werden alle nachfolgenden Zeichenoperationen von Thread 2 natürlich auf dem Bild von Thread 2 vorgenommen, weil dieser Thread als letztes 'StartDrawing()' aufgerufen hat.
Ich muss aber dazu sagen, dass ich auch noch nicht getestet habe. Aber da man bei den Zeichenbefehlen nicht angeben kann auf welchem Bild man malen möchte, sondern das ganze durch 'StartDrawing()' festgelegt wird, glaube ich nicht, dass Purebasic für jeden Thread ein eigenes unabhängiges 'StartDrawing()' zulässt.
Laut Hilfe (StartDrawing) hat jeder Thread seine eigene Ausgabe:
Hilfe hat geschrieben:Wenn "Erstelle threadsicheres Executable" in den Compiler-Optionen aktiviert ist, dann hat jeder Thread seine eigene aktuelle Zeichenausgabe. Dies bedeutet, dass zwei Threads zur gleichen Zeit auf verschiedene Ausgaben zeichnen können.
Cool, wunderbar. Dann hab ich das entweder noch nie gelesen oder es kam erst in den letzten paar Jahren da rein. Ich lese eindeutig zu selten die Hilfe.
STARGÅTE hat geschrieben:Stattdessen würde ich lieber am Anfang je nach anzahl der Kerne, 2-8 Threads erstellen. Das heißt, die Verarbeitungsschleife laufen schon alle im "Ruhemodus" und warten auf eine Aufgabe. Danach verteilst du zB deine 100 Aufgaben gleichmäßig auf die Threads, in denen sie dann wieder "normal" nacheinander abgearbeitet werden.
Angenommen ich erstelle 2 Threads, wie würde das dann codetechnisch aussehen? So?
Procedure Verarbeitung()
ForEach ImagesToProcess()
; Verarbeitung
Next
EndProcedure
Thread1 = CreateThread(@Verarbeitung(), *1) ; verarbeitet alle ungeraden zahlen (1,3,5,7,...)
Thread2 = CreateThread(@Verarbeitung(), *2) ; verarbeitet alle geraden zahlen (2,4,6,8,...)
; Threads laufen im Leerlauf da ImagesToProcess() ohne Inhalt
; Images() nach ImagesToProcess kopieren damit Threads zu tun haben
; mit IsThread() abfragen ob beide Threads "fertig" sind