Strings in Threads ohne "Threadsafe"

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

Crasht bei mir ebenso nicht. Der Code von Fluid Byte crasht bei mir aber ebenfalls nicht allerdings habe ich keinen Zweifel daran das er es bei ihm tut.

Um nochmal auf die CPU zurückzukommen: Ich hab nen AMD Athlon XP.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
helpy
Beiträge: 635
Registriert: 29.08.2004 13:29

Beitrag von helpy »

Hallo PMV,

Meiner Meinung sagt folgendes ...
With threadsave mode on all the commands are threadsafe as long as they are used on resources local to the thread.
... doch etwas über Strings aus ... gerade auch was Dein letztes Beispiel betrifft ... dort verwendest Du doch die lokale Resource String.

Für nicht lokale (shared) Resourcen gilt:
As soon as something shared is used, there needs to be a protection.
Mag sein, dass ich den Begriff "lokale Resource" nicht richtig interpretiere.
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Der Code von PMV crashed bei mir ebenfalls. :shock:
Windows 10 Pro, 64-Bit / Outtakes | Derek
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Beitrag von freak »

Bei Threads bedeutet kein Crash noch lange nicht das das Program auch korrekt ist. Schließlich führt fehlende Synchronisation nur beim richtigen Timing zu einem Crash.
Man kann sich also bei Threads nie aufs Ausprobieren verlassen, sondern muss Warnungen ernst nehmen, auch wenn es beim Test zu funktionieren scheint.
http://www.purebasic.com/german/documentation/thread/index.html hat geschrieben:Es ist dennoch möglich, Threads ohne diesen Modus zu erstellen, aber nicht empfehlenswert, da selbst eine einfache Sache wie der lokale Zugriff auf Strings gefährlich sein kann und geschützt werden muss.
Schonmal das Beispiel auf einem Multicore getestet ? Hier crasht es sofort ohne Threadsafe. (Core2Quad)
Fluid Byte hat laut Profil auch einen Dualcore.

Auf einem Singlecore ist es kein Wunder das das Beispiel funktioniert. Da es bei dem Delay() immer zu einem Kontext-switch kommt ist die Wahrscheinlichkeit das ein Thread der die meiste Zeit mit Schlafen verbringt exakt in der String-Operation unterbrochen wird extrem gering.
Selbst ohne das Delay() ist die Wahrscheinlichkeit eines Konfliktes bei einem Singlecore weit geringer als bei einem Multicore weil dort die Threads wirklich parallel laufen und nicht nur pseudo-parallel.

Thema Strings:
String-Operationen verwenden in PB einen globalen Speicherbereich um die Anzahl der Allocations zu verringern, was bei Threads unweigerlich zu Problemen führt.
Selbst wenn es nicht gleich ein Crash ist kann es leicht zu falschen String-Ergebnissen kommen.

Also, Strings+Threads = Threadsafe ist ein Muss. Alles andere ist Lotto.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

:allright:

Das ist die erste offizielle Aussage, die ich jetzt zu dem Thema lesen durfte.
Würd mich auch tierisch über die nun herschende Klarheit freuen ... wenn
ich mir nicht jetzt gedanken über mein Programm machen müsste :cry:

@freak ... schützt Threadsafe diesen globalen Speicherbereich für Strings
oder wird die Anzahl der Speicherreservierungen wieder erhöht?

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Beitrag von freak »

Mit Threadsafe bekommt jeder Thread seinen eigenen Stringbuffer. (Verwaltet über threadlocal storage)
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

Das dürfte doch die Lösung für lokale Strings sein, oder?
Durch diesen lokalen Puffer für jeden Thread wird sicher gestellt, das die
Stringoperationen der einzellnen Threads sich nicht mehr beeinflussen.
Müsste das nicht auch ohne Threadsafe realisierbar sein. Ich mein, ein
Thread wird mit PB ja nur über CreateThread() erstellt, oder muss der
Compiler das vorher wissen? Eventuell wäre dann ein entsprechendes
Schlüsselwort mal interessant (anstelle von "Procedure").

Nur ne Frage, ob das so einfach wäre :D
Threadsafe im gesamten Programm aktivieren, weil es einen Thread gibt,
der für die Ausgabe genutzt wird ... find ich persönlich überdimensioniert :D
Wenn ich mich jetzt nicht vertue macht Threadsafe ja noch (viel) mehr.

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Beitrag von freak »

TLS ist einiges langsamer als ein direkter Pointer. Desshalb gibt es ja überhaupt die Threadsafe option. Und nein, das geht nicht für einen Teil des Codes weil dafür andere Funktionen gelinkt werden müssen, und dein Thread ja auch andere Prozeduren aufrufen kann.

> Threadsafe im gesamten Programm aktivieren, weil es einen Thread gibt, der für die Ausgabe genutzt wird ... find ich persönlich überdimensioniert

Dann solltest du dir vielleicht überlegen ob der Thread dann überhaupt nötig ist.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

Das stimmt ... mit der Info muss ich mir da echt noch mal gedanken drüber
machen, wie es anders gelöst werden kann ... aber zum glück ist das nen
unwichtigeres Projekt, wo das zeit hat.

Danke noch mal für die Info. :D

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Hallo Freak, schön das du zu dem Thema was schreibst.

So brauche ich nicht mehr viel dazu schreiben. Ein Programmcrash ist bei mir auch nicht zwangsläufig ein direkter Absturz des Programmes, sondern für mich auch einfach eine inkorrekte Datenbehandlung.
Da einfach keiner außer den Programmierern sagen kann, wie die Stringverwaltung genau funktioniert, KÖNNTE es ja auch ausreichen, wenn einfach mal die Daten nicht korrekt oder an falscher Stelle geschrieben wären. Das Codebeispiel z.B. müßte theoretisch bei jeder Änderung auch überprüfen ob auch die Daten im string genau so sind wie es sein müßte. Also sagen wir mal gleichzeitig je Thrad noch ein Thread der threadsafe ist und die ausgaben vergleich. Da ein Thread mit Strings aber nie sicher sein kann, wenn mindestens ein Thread unsicher ist, so ist selbst ein sicheres testen unmöglich.

Mir sind bisher auch quasi keine Fehler im Programm aufgefallen, da aber damals (Freak gehört ja auch zum engen PB-kreis) ganz klar gesagt wurde wie es aussieht und das definitiv auch die interne Stringverwaltung beachtet werden muß, so wollte ich euch nur darauf hinweisen.

Ich bin kein Topprogrammierer, weil ich halt auch recht wenig mache, aber ich versuche einfach seit meiner Kindheit Fehlerquellen auszuschliesen.
So z.B. habe ich eine Procedure, jetzt ein Macro das ich anstatt von addelement und creatememory usw. nutze. die meisten überprüfen nicht ob auch überall der speicher korrekt erstellt wurde (besonders wenn man oft speicher allokiert). bei mir wir wenigstens der Code so lange nicht weiter ausgeführt bis Speicher allokiert wurde. Und sei es noch so unwahrscheinlich das Addelement mal einen Fehler auslöst.

Daher hier auch meine "Stringhinweise".
Thema Strings:
String-Operationen verwenden in PB einen globalen Speicherbereich um die Anzahl der Allocations zu verringern, was bei Threads unweigerlich zu Problemen führt.
Selbst wenn es nicht gleich ein Crash ist kann es leicht zu falschen String-Ergebnissen kommen.

Also, Strings+Threads = Threadsafe ist ein Muss. Alles andere ist Lotto.
Das ist es was ich meinte, so aber leider auch noch icht in der Deutlichkeit laß.
Das heißt faktisch, das jeder so programmieren muß wie ich es gesagt habe. Komplett die gesammte Stringverwendung (Variablen, Befehle, Funkionen, denke auch mal Konstanten) muß mit einem einzigen Mutex gesichert sein. Dennoch kann dies bei Programmen die Geschwindigkeitsoptimiert sind sehr vorteilhaft sein. Und mit ein wenig "basteln" (Macros, Proceduren) kann man das recht leicht hinbekommen. Einzig vergessen darf man dann nix ;-)


@Freak:
ich denke einer von uns oder wir gemeinsam, sollten mal einen kurzen Text erstellen, der genau das was du jetzt geschrieben hast beinhaltet und dann mit in die PBhilfe unter Threads bzw. "threadsafe" eingefügt wird, damit es wirklich alle genau verstehen.
Ich bedanke mich mal wieder herzlichst bei dir für deine klare und gute Hilfe. (obwohl ich bis auf den globalen Speicherbereich ja schon aufgeklärt war)

@pmv:
bis dahin einfach threadsafe nutzen. PB ist ja keine Schnecke, da sollte es vorläufig auch mal so gehen :-)

@myself: Puh, ausnahmsweise mal gut, daß ich so nervig und stur geblieben bin. Jetzt hat es ja echt mal Licht ins dunkel gebracht :-)
1. Win10
PB6.1
Antworten