Seite 1 von 1
Dynamisch Threads starten und Prozeduren aufrufen
Verfasst: 18.02.2014 00:48
von Delle
Hallo,
aktuell wird bei einem Programm alles nacheinander in einer Schleife abgearbeitet und anschließend die gesammelten Ergebnisse mittels ausgabe$ ausgegeben:
Code: Alles auswählen
ForEach Images()
load$=Images()\ImagePath.s
; Verarbeitung
ausgabe$+bildergebnis$
FreeImage(Images()\ImageID)
DeleteElement(Images())
Next
Debug ausgabe$
Nun soll aus Zeitgründen alles
gleichzeitig bearbeitet werden, nicht mehr hintereinander.
Also im Prinzip so:
Code: Alles auswählen
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?
Danke,
Delle
Re: Dynamisch Threads starten und Prozeduren aufrufen
Verfasst: 18.02.2014 01:02
von STARGÅTE
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.
Ich hoffe meine Bildsprache ist verständlich.
Re: Dynamisch Threads starten und Prozeduren aufrufen
Verfasst: 18.02.2014 01:50
von NicTheQuick
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.
Re: Dynamisch Threads starten und Prozeduren aufrufen
Verfasst: 18.02.2014 01:58
von matbal
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.
Re: Dynamisch Threads starten und Prozeduren aufrufen
Verfasst: 18.02.2014 02:24
von NicTheQuick
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.

Re: Dynamisch Threads starten und Prozeduren aufrufen
Verfasst: 18.02.2014 03:12
von Delle
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?
Code: Alles auswählen
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
Re: Dynamisch Threads starten und Prozeduren aufrufen
Verfasst: 18.02.2014 03:47
von NicTheQuick
Zum Beispiel nimmst du meine ConcurrentQueue:
[PB] HowTo: ConcurrentQueue
Den endgültigen Code findest du in der Videobeschreibung.