Aktuelle Zeit: 24.08.2019 09:04

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: FAQ: Threads in PB
BeitragVerfasst: 26.11.2008 18:48 
Offline
Benutzeravatar

Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg
Folgender Text wurde von mir in Fließarbeit erstellt und nicht auf Rechtschreib- oder Gramatikfehler überprüft. Der Inhalt ist mit Quellen belegt. Aufgrund meiner Zeitknappheit komm ich so schnell nicht dazu, den Text zu verbessern/ erweitern und Poste ihn daher "unfertig". Zusätzliche Inhalte können gerne dazu gepostet werden. Sollte ich irgend wann mal wieder die Zeit dazu finden werd ich das dann auch dazu schreiben und eventuell sogar ins englische übersetzen ... obwohl das vermutlich eh besser wer anders machen sollte /:->

-------------------------------------------------------------
Stand PB4.20 + PB4.30 B4

Ich bin Anfänger, kann ich trotzdem Threads verwenden?
Threads bedeuten ein hohes Risiko für die Programmstabilität. Threads gehören zu einem der letzten Kapitel, die ein PB-Programmierer lernen sollte. Um mit Threads sauber arbeiten zu können muss vor dem Programmieren genau überlegt werden, was benötigt wird und wie das Programm funktionieren soll. Fehlerhaftes nutzen von Threads führt in jedem Fall zur instabilität eines Programms und damit meistens undefinierten Fehlern!



Wofür sind Threads?
In prozeduralen Sprachen wie PureBasic wird jedes Programm von "oben nach unten" abgearbeitet. Dabei fängt das Programm in der Zeile an, in der der erste ausführbare Quellcode zu finden ist. Mit Schleifen, If-Anweisungen und Prozeduren kann der Programmfluss beeinflusst werden, in jedem fall wird aber zum gleichen Zeitpunkt immer nur ein Befehl ausgeführt. Wird ein Thread benutzt, ändert sich dies, da jeder Thread seinen eigenen Programmfluss unabhänig vom Hauptthread hat. Durch Threads können also in der theorie mehrere Befehle gleichzeitig ausgeführt werden.



Was macht die Compileroption Threadsafe?
Die Behandlung von Strings und einigen PB-Befehle werden intern geändert. Strings haben normal einen globalen Speicherpuffer für sämtliche Operationen. Diese Lösung führt bei Threads aber zu großen Problemen. Mit der Compileroption bekommt jeder Thread seinen eigenen Puffer (localstring storage), wodurch das Problem gelöst wird. Diese Lösung geht aber auf Kosten der Geschwindigkeit, weshalb diese Compileroption auch nur bei Threads verwendet werden sollte. Desweiteren bestehen die PB-Befehele logischerweise nicht aus einzellnen Anweisungen, sondern aus teilweise sogar sehr komplexen Befehlsketten, die ohne weiteres nicht gleichzeitig von mehreren Orten aus verwendet werden dürfen. Durch Threadsafe werden also alle weiteren PB-Befehle intern gesichert.



Was muss ich bei der Verwendung von Threads beachten?
In eigentlich jedem Fall ist "Threadsafe" zu aktivieren, da das manuelle Sichern sämtlicher Stringoperationen den Sinn eines Threads aushebeln würde und kaum einer den überblick hat, welche PB-Befehle sonnst noch gesichert werden müssen.

Fenster in Threads sind ein weiteres spezielles Thema:
- Unter Windows muss jeder Thread, der seine eigenen GUI-Elemente erstellt einen Eventloop haben. Das heißt WindowEvent() muss in dem entsprechenden Thread genutzt werden, wenn z.b. Gadgets, Toolbars, Fenster, Menüs oder eine Statusbar genutzt wird.
- Unter Linux hingegen darf nur der Hauptthread eine Eventloop haben. Auch GUI-Elemente sollten nach Möglichkeit nur dort erstellt werden.
- Unter Mac OS X sind Eventloops ebenfalls nur im Hauptthread erlaubt.
Gadgets dürfen nur auf Fenster des eigenen Threads erstellt werden, da die Eventbehandlung sonnst durcheinander kommt. Für die Platformunabhängigkeit sollte also der Hauptthread alles erstellen und Threads greifen nur verändernd auf diese Elemente zu.

DirectX darf in nur einem Thread verwendet werden, das ist eine Einschränkung von Microsoft. Egal ob es der Hauptthread ist oder ein anderer, es müssen allerdings sämtliche Init-Befehle die damit zu tun haben in dem Thread aufgerufen werden, der diese Befehle benutzt.

Der Befehl KillThread() existiert zwar, darf aber nur in wirklichen Notfällen genutzt werden. Wird ein Thread trotzdem mit diesem Befehl zum abstürzen gebracht, können Ressorcen nicht aufgeräumt werden. Selbst Microsoft warnt davor, diesen Befehl zu verwenden. Der wirklich einzige Zweck, den dieser Befehl hat, ist fals sich ein Thread aufhängt ihn trotzdem beenden zu können, z.b. weil er die CPU auslastet.

Bei den Netzwerkbefehlen ist das Erstellen und Schließen eines Servers nicht sicher, genau so wie dessen Ereignisbehandlung dürfen mehrere Threads nicht gleichzeitig diese Befehle nutzen können. Für Multiserverprogramme müssen die Serverfunktionen also manuell abgesichert werden.

Der Debugger von PureBasic arbeitet bei Threads ohne Threadsafe nicht richtig. Zwar sollte es ohne Threadsafe kein Absturz geben, allerdings dürfen dann nach "Debug" keine Stringoperationen getätigt werden. Die Informationen des Debuggers sind aber sehr wahrscheinlich ohne Threadsafe falsch, z.B. die Zeilennummer.

Globale/ geteilte Ressorcen müssen zusätzlich geschützt werden. Ausgenommen sind nur die einfachen Variablentypen Byte, Word, Long, Float, Zeiger und Integer. Nur in x64 Programmen sind auch Quads und Doubles unproblematisch. Wird mit diesen Variablen in mehreren Threads gearbeitet, sind keine Probleme zu befürchten. Bei komplexeren Datenstrukturen ist immer vorsicht geboten, da hier nur ein Thread zur selben zeit zugreifen darf.

Die Konsole ist eine geteile Ressorce. Da PB das nicht selber macht muss auch der Zugriff auf diese geschützt werden. (ändert sich das noch in PB V4.30?)



Wie schütze ich globale/ geteilte Ressorcen?
PureBasic bietet in der Threadbibliothek zusätzliche Befehle um kritischen Programmcode mit einem Mutex zu schützen. Ein Mutex ist ein spezielles Objekt, dass zur selben Zeit immer nur von einem Thread gesperrt werden kann. Hat ein Thread also ein Mutex erfolgreich gesperrt, hat kein anderer Thread diesen Mutex gesperrt und es kann bedenkenlos auf die entsprechende Ressorce zugegriffen werden. Nach dem Zugriff muss der Thread das Mutex wieder entsperren. Ein Mutex wird durch die Programmlogik einer Ressorce zugewiesen, das heißt der Programmierer muss selber wissen, welches Mutex gesperrt werden muss, um sicher auf eine geteilte Ressorce zugreifen zu können. Das Sperren muss für jeden, wirklich jeden Zugriff auf die Ressorce getätigt werden, sobald mehrere Threads diese Ressorce gleichzeitig nutzen.



Was sind Deadlocks und wodurch entstehen diese?
Wartet Thread A auf ein Mutex, welches von Thread B gesperrt wurde und wartet gleichzeitig Thrad B auf ein Mutex, das von Thread A bereits gesperrt wurde kann die Programmausführung nicht mehr fortgesetzt werden. Dies nennt man Deadlock. Um dieses Problem zu vermeiden ist es notwenig, Mutex immer in der selben Reihenfolge zu sperren. Gibt es z.B. 3 Stück: A, B und C und man stellt sicher, das immer zuerst A, dann B und zuletzt C gesperrt werden, können solche Deadlocks nicht durch das Sperren einstehen. Werden A, B und C unabhängig voneinander benutzt, also kein Thread sperrt gleichzeitig 2 oder 3 Stück, so ist ebenfalls ein Deadlock ausgeschlossen.



In welchen Situationen sind Threads zu empfehlen?
Eine direkte Empfehlung gibt es wohl nicht. Die meisten Probleme für die Threads in frage kommen, sind auch genau so gut ohne lösbar. Der Sinn oder Unsinn dahinter liegt letztendlich im Auge des Programmierers, der sich selber wirklich gut überlegen sollte, ob Threads wirklich einen größeren Vorteil bieten. Bevor sich jemand allerdings wirklich mit diesem Thema beschäftigt sollte wohl einiges an Erfahrung auf zu weisen sein.

Rechenintensive Operationen, die sich nicht kurzeitig unberbrechen lassen wären allerdings ein guter Grund, da der Benutzer sonnst schnell den Eindruck bekommt, das Programm wäre abgestürzt. Situationen mit verschiedenen Antwortzeiten oder Intervallen können auch ein Grund für Threads sein. Und dank der heutigen Multicore(Mehrkern)-Prozessoren sind Threads für rechenintensive Operationen besonders Empfehlenswert, sofern sich diese auf mehrere Kerne aufteilen lassen, da jeder Kern im Idealfall einen anderen Thread ausführen kann und das Programm ohne Threads nur einen Kern zur verfügung hat.




Quellen:
- GUI in Windows und Linux:
http://www.purebasic.fr/german/viewtopi ... 18&start=0
- GUI in Mac OS X
http://www.purebasic.fr/english/viewtop ... 13&t=45422
- KillThread()
http://www.purebasic.fr/german/viewtopi ... 08&start=0
- globale Stringverwaltung
http://www.purebasic.fr/german/viewtopi ... 8&start=30
- Was ist die Idee hinter Threadsafe?
http://www.purebasic.fr/german/viewtopi ... 6&start=10
- Netzwerkbefehle/ Debugger/ Konsole
http://www.purebasic.fr/english/viewtopic.php?t=31803
- geteilte Ressorcen
http://www.purebasic.fr/english/viewtopic.php?t=29581

_________________
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-


Zuletzt geändert von PMV am 15.04.2012 22:45, insgesamt 2-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: 26.11.2008 19:41 
Offline
Benutzeravatar

Registriert: 11.05.2008 00:22
Wohnort: Bodensee
Cool danke für die Info !


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: 26.11.2008 23:50 
Offline
Benutzeravatar

Registriert: 28.07.2005 12:39
Zitat:
DirectX darf in keinem Thread verwendet werden, das ist eine Einschränkung von Microsoft


Das ist falsch, man darf es sehr wohl. Man sollte allerdings nur einen
Thread nutzen, Mainthread oder einen erstellten Thread ist dabei egal.

Wer mehr ueber Threads wissen moechte (von wegen Sinn usw) sollte mal
im "Petzold" nachschlagen.

_________________
Suche


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: 27.11.2008 00:18 
Offline
Benutzeravatar

Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg
Ich hab die PB-Hilfe lediglich umformuliert, aber du hast natürlich recht,
hab ich ja auch schon anders benutzt ^_^ ... ich änder das entsprechend
ab. Mal davon abgesehen das die Forumlierung auch unlogisch war, denn
der Hauptthread ist ja auch ein Thread. :lol:

MFG PMV

_________________
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-


Zuletzt geändert von PMV am 27.11.2008 00:22, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: 27.11.2008 00:21 
Offline
Ein Admin
Benutzeravatar

Registriert: 29.08.2004 20:20
Wohnort: Saarbrücken
Doubles gehören meines Wissens auch zu den einfachen Datentypen, die keine Probleme
in Threads machen. Quads bestimmt auch, aber da muss man mal die ASM-Freaks hier
fragen.

_________________
Freakscorner.de - Der Bastelkeller | Neustes Video: Neje DK - 1 Watt Laser Engraver
Ubuntu Gnome 18.04.1 LTS x64, PureBasic 5.60 x64 (außerdem 4.41, 4.50, 4.61, 5.00, 5.10, 5.11, 5.21, 5.22, 5.30, 5.31, 5.40, 5.50)
"Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen – Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: 27.11.2008 00:24 
Offline
Benutzeravatar

Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg
Hab ich Freak bereits gefragt und er hat mir das so bestätig.

MFG PMV

_________________
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: 27.11.2008 00:50 
Offline
Benutzeravatar

Registriert: 12.06.2005 11:15
Wohnort: Germany
NicTheQuick hat geschrieben:
Doubles gehören meines Wissens auch zu den einfachen Datentypen, die keine Probleme
in Threads machen. Quads bestimmt auch, aber da muss man mal die ASM-Freaks hier
fragen.

Nene, is schon richtig so. Um auf Quads zuzugreifen auf einem 32bit System sind 2 Instuktionen nötig. Deswegen nicht save.

_________________
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FAQ: Threads in PB
BeitragVerfasst: 15.04.2012 22:48 
Offline
Benutzeravatar

Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg
Fred hat im englischen Forum erwähnt, das auch unter
Mac OS X der Eventloop für Fenster nur im Hauptthread sein darf.
Den kleinen Eintrag hab ich nun entsprechend hinzugefügt.

_________________
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FAQ: Threads in PB
BeitragVerfasst: 03.05.2012 17:48 
Offline
Benutzeravatar

Registriert: 18.04.2006 17:01
Wohnort: Bavaria
Mit Verlaub, damit ich das richtig verstanden habe:

Ich muss derzeit keinen Zugriff auf globale Strings Mutex-schützen!?
ein "threadsafe" reicht voll aus?
(bisher, zumindest, hatte ich da keine Probleme :) )

Code:

Code:
Global text.s

Procedure hallo ( void)
    startzeit = ElapsedMilliseconds() + 5000
    Repeat
    text = Str(Random ( 50000))
    Delay(1)
    PrintN(text)
    Until startzeit < ElapsedMilliseconds()
EndProcedure

OpenConsole ()
For x = 1 To 50
CreateThread ( @hallo () , 0)
Next

Input ()


Mfg Max

_________________
Max Aigner Projects


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FAQ: Threads in PB
BeitragVerfasst: 03.05.2012 22:58 
Offline
Kommando SG1
Benutzeravatar

Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Vorsicht, du vermischst in deinem Beispiel jetzt verschiedene Sachen.

Thread-Safe ist einzig und alleine dafür da, dass sichergestellt wird, dass der allgemeine Umgang mit Strings sicher ist (selbst wenn sie protected wären).
Wäre Thread-Safe aus, könnten sogar IMAs entstehen, obwohl der String garnicht global ist.
Bei Thread-Safe geht es nur darum, dass ein String (wenn er zB erweitert wird) nicht in den Speicher missbraucht, den gerade ein andere Thread für seinen String nützen möchte.

Wenn es darum geht gleichzeitig eine globale String-Variable zu beschreiben, dann ist Mutex pflicht!

Dei Beispiel erzeugt bei mir zB totalen Müll und ein Overflow.
Zitat:
8589
8589
8589
8589
­¡♂1135
­¡♂1135
­¡♂1135
­¡♂1135
­¡♂1135
26223
26223
26223


Mutex muss nicht sein, wenn es um Typen wie Long, Integer, Float usw. geht, da diese mit einem Zyklus geschrieben oder gelesen werden.

_________________
Bild
 
BildBildBild


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ]  Gehe zu Seite 1, 2  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye