Dynamisch Threads starten und Prozeduren aufrufen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Delle
Beiträge: 1130
Registriert: 10.05.2005 22:48

Dynamisch Threads starten und Prozeduren aufrufen

Beitrag 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
PB 6.21 | Win 11
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Dynamisch Threads starten und Prozeduren aufrufen

Beitrag 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.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Dynamisch Threads starten und Prozeduren aufrufen

Beitrag 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.
matbal
Beiträge: 261
Registriert: 30.03.2011 20:53

Re: Dynamisch Threads starten und Prozeduren aufrufen

Beitrag 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.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Dynamisch Threads starten und Prozeduren aufrufen

Beitrag 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. :lol:
Benutzeravatar
Delle
Beiträge: 1130
Registriert: 10.05.2005 22:48

Re: Dynamisch Threads starten und Prozeduren aufrufen

Beitrag 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

PB 6.21 | Win 11
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Dynamisch Threads starten und Prozeduren aufrufen

Beitrag von NicTheQuick »

Zum Beispiel nimmst du meine ConcurrentQueue: [PB] HowTo: ConcurrentQueue
Den endgültigen Code findest du in der Videobeschreibung.
Antworten