Tutorial: Parallele Programmierung in PB

Hier kannst du häufig gestellte Fragen/Antworten und Tutorials lesen und schreiben.
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Tutorial: Parallele Programmierung in PB

Beitrag von cxAlex »

Parallele Programmierung wird dieser Tage immer wichtiger. DualCore ist schon Standart, QuadCore auch schon fast normal und bis 2010 will Intel 6 Kern Desktop CPUs herausbringen.

Um die Power mehrerer Prozessorkerne zu nutzen muss man aber zwangsläufig auf Threads setzen, ansonst hat man genau gar nichts davon.

Nun sehe ich hier im Forum immer wieder Leute die vor Threads zurückschrecken (eben weil Sie sie nicht verstehen), total falsche Verwendung und auch sonst die abenteuerlichsten Verwendungen von Threads.

Also muss ein Tutorial her. :mrgreen:

Parallele Programmierung in PB: Threads & mehr

Geplant:
  • Threads in PB
  • Thread - Kommunikation
  • Verwaltung mehrer Threads
  • Synchronisation von Threads
  • Gefahren bei der Verwendung von Threads (Death Lock, Race Conditions, ...)
Wenn anderweitige Fragen auftauchen werde ich versuchen auch diese zu beantworten.

Ich würde mit dem Tutorial morgen oder am Montag beginnen, besteht Interesse?

Gruß, Alex
Zuletzt geändert von cxAlex am 30.03.2009 08:50, insgesamt 1-mal geändert.
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Tutorial: Parallele Programmierung in PB

Beitrag von ts-soft »

cxAlex hat geschrieben:DualCore ist schon Sandart
Bei Netbook oder Notebook am Strand dürfte das hinhauen :mrgreen:
cxAlex hat geschrieben: Ich würde mit dem Tutorial morgen oder am Montag beginnen, besteht Interesse?
Sicherlich doch :allright:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
X360 Andy
Beiträge: 1206
Registriert: 11.05.2008 00:22
Wohnort: Bodensee
Kontaktdaten:

Re: Tutorial: Parallele Programmierung in PB

Beitrag von X360 Andy »

cxAlex hat geschrieben:
Ich würde mit dem Tutorial morgen oder am Montag beginnen, besteht Interesse?
Immer doch :allright:
Aber gab es sowas bzw gibt es sowas nicht schon ? (Hab leider grad keine Zeit zum suchen)
Benutzeravatar
KeyKon
Beiträge: 1412
Registriert: 10.09.2004 20:51
Computerausstattung: Laptop: i5 2,8 Ghz, 16GB DDR3 RAM, GeForce 555GT 2GB VRAM
PC: i7 4,3 Ghz, 32GB DDR3 RAM, GeForce 680 GTX 4GB VRAM
Win10 x64 Home/Prof
PB 5.30 (64bit)
Wohnort: Ansbach
Kontaktdaten:

Beitrag von KeyKon »

Auf jeden Fall :allright:
(\/) (°,,,°) (\/)
Andesdaf
Moderator
Beiträge: 2673
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Beitrag von Andesdaf »

cxAlex hat geschrieben:Ich würde mit dem Tutorial morgen oder am Montag beginnen, besteht Interesse?
keine Frage :)
Win11 x64 | PB 6.20
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

Toll das so viel Interesse besteht. Ich denke es wird eher Montag als morgen werden, aber vlt. krieg ichs hin schon morgen die ersten Schritte zu posten.

@X360 Andy:

Es gibt eine Erklärung was Threads sind und was man damit machen darf und was nicht (Windows/PB/DX/... - Einschränkungen) von PMV, dort werden aber keine Beispiele oder Anwendungsmöglichkeiten erklärt oder vorgezeigt.

Übrigens empfehle ich PMVs Thread vor dem Tutorial zu lesen:

http://www.purebasic.fr/german/viewtopic.php?t=18374

Gruß, Alex
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

Grundlagen: Threads in PB

PB stellt einem schon von Haus aus Funktionen zur Erstellung und Verwaltung von Threads bereit. Warum man Pause/Resume/Kill-Thread eher vermeiden sollte werde ich später im Tutorial noch erläutern.

Wie starte ich einen Thread in PB?

Dafür gibt es in PB den Befehl CreateThread(). Dieser erwartet den Pointer auf eine Procedure, und einen Übergabeparameter. Wobei wir schon bei der 1. Fehlerquelle währen:

Wichtig: Auch wenn euer Thread diesen Parameter nicht braucht müsst ihr ihn in die Procedurenparameter schreiben, sonst kommt es früher oder später zu einem Stack Fehler.

Nun starten wir unseren 1. Thread mit PB:

Code: Alles auswählen

; Thread Procedure. Parameter nicht vergessen!
Procedure MyThread(dummy)
  MessageRequester("Thread", "Ich bin ein Thread")
EndProcedure

; Thread erstellen. Pointer auf Procedure mit @ ermitteln
Thread = CreateThread(@MyThread(), 0)
MessageRequester("Main", "Ich bin das Hauptprogramm")
Das war ja noch gar nicht so schwer. Nun wollen wir dem Thread aber natürlich auch Parameter übergeben, in diesem Beispiel den Text der angezeigt werden soll:

Wichtig: Sobald in Threads Strings vorkommen sollte man immer die Compiler-Option Thread-Safe verwenden.

Code: Alles auswählen

; Thread Procedure.
Procedure MyThread(*Text.s)
  MessageRequester("Thread", *Text)
EndProcedure

; Thread erstellen. Pointer auf Procedure mit @ ermitteln
; Nun übergeben wir einen Parameter
Text.s = "Ich bin ein Thread"
Thread = CreateThread(@MyThread(), @Text)
MessageRequester("Main", "Ich bin das Hauptprogramm")
Auch bis hierher noch ganz einfach. Nun wollen wir aber meist nicht nur einen Parameter übergeben sondern mehrere. Da man an den Thread nur 1. übergeben kann lösen wir das ganze mit einer Struktur, in die wir alle Werte schreiben die wir brauchen, und an den Thread übergeben. Dafür schreiben wir uns eine kleine Launcher Procedure:

Code: Alles auswählen

; Thread Parameter
Structure Thread_Parameter
  *Title ; Titel
  *Text ; Text
  Flags.i ;Parameter
EndStructure

; Thread Procedure
Procedure MyThread(*Thread.Thread_Parameter)
  Protected Title.s, Text.s
  Title.s = PeekS(*Thread\Title)
  Text.s = PeekS(*Thread\Text)
  MessageRequester(Title, Text, *Thread\Flags)
 
  ; Speicher aufräumen
  FreeMemory(*Thread\Title)
  FreeMemory(*Thread\Text)
  FreeMemory(*Thread)
EndProcedure

; Thread - Starter
Procedure Thread_Launcher(Title.s, Text.s, Flags = 0)
  ; Neue Thread - Parameter anlegen
  Protected *Thread.Thread_Parameter = AllocateMemory(SizeOf(Thread_Parameter))
 
  ; Thread - Paramter schreiben
 
  ; Ich verwende absichtlich keine nativen Strings in der Struktur da man diese
  ; manuell freigeben müsste, daher Speicherblöcke
  *Thread\Title = AllocateMemory(StringByteLength(Title) + SizeOf(Character))
  PokeS(*Thread\Title, Title)
  *Thread\Text = AllocateMemory(StringByteLength(Text) + SizeOf(Character))
  PokeS(*Thread\Text, Text)
  *Thread\Flags = Flags

  Thread = CreateThread(@MyThread(), *Thread)
 
  ProcedureReturn Thread
EndProcedure

; Thread starten
Thread_Launcher("Thread","Ich bin ein Thread")
Thread_Launcher("Thread","Ich bin auch ein Thread")
MessageRequester("Main", "Ich bin das Hauptprogramm")
Wichtig: Der Thread muss seine Parameter am Ende immer freigeben, sonst ensteht ein Memory - Leak

So, nun haben wir bereit ein Anwendungsbeispiel: eine MessageBox die die Programmausführung nicht blockiert.
Das war ein kleines Beispiel wie man Threads in PB erstellen kann. Eigentlich sollte bis hierher alles klar sein, wenn es Fragen gibt nur her damit!
Zuletzt geändert von cxAlex am 29.03.2009 18:25, insgesamt 2-mal geändert.
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

muß es nicht heißen *Thread\Flags = Flags anstatt Flags = Flags ?

du schreibst
; Ich verwende absichtlich keine nativen Strings in der Struktur da man diese
; manuell freigeben müsste, daher Speicherblöcke
was heißt das genau ?? du gibst doch mit FreeMemory(*Thread\Title) alles einzeln frei.

Ansonsten weitermachen, da ich bisher mit THREADS noch garnichts gemacht habe und es eigentlich auch nicht nötig war, wer weiß das schon, werde ich deine Posts aufmerksam verfolgen :allright:
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

hjbremer hat geschrieben:muß es nicht heißen *Thread\Flags = Flags anstatt Flags = Flags ?
Ups, kleiner Tippfehler, danke.
; Ich verwende absichtlich keine nativen Strings in der Struktur da man diese
; manuell freigeben müsste, daher Speicherblöcke
> was heißt das genau ?? du gibst doch mit FreeMemory(*Thread\Title) alles einzeln frei.

Ich verwende kein Title.s, Text.s, sondern eben *Title, *Text und speicher alles in Speicherblöcke, also ich verwende keine nativen PB Strings da sonst der PB Stringmanager mitmischen würde und ich eine extra Funktion zum freigeben der Strings in der Struktur brauchen würde.
(Es gibt schon einen Weg dafür aber der kann sich mit der nächsten PB - Version schon wieder ändern und so sollte es immer gehen)
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

ein kleines Problem nun
wenn ich in Compileroptionen threadsicheres Executable erstellen einschalte gibt es einen readerror at adress 8 mit PB 4.3

und gerade mit 4.2 getestet, da gehts
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Antworten