Strings in Threads ohne "Threadsafe"

Anfängerfragen zum Programmieren mit PureBasic.
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

@Fluid Byte:
Du mußt natürlich wenn du nicht "threadsafe" nutzt unbedingt bei JEDER Stringnutzung in JEDEM thred den selben Mutzex nutzen. vergißt du es nur einmal cracht es irgendwann.

@Thorium:
Das der Mutex da nix bringt ist klar. Da du ja nur von einer Stelle aus auf die Highscore zugreifst. Ein Mutex bringt nur was, wenn mehrere Codestellen auf die gleiche Ressource (z.b. String) zugreifen.
Leider total falsch. Wenn du z.b mutex a& nutzt um sting b$ zu schützen MUßT (!!!) du bei ALLEN Stings des kompletten Programms diese mit dem Mutex a& schutzen. Bei Stings kommt im gegensatz zu anderen Variablentypen nicht nur ein schreibfehler bei der bestimmten Stringvariablen irgendwann vor, sondern zu ganze Stringverwaltung kommt durcheinander. So wurde es auf jedenfall mal von Fred erklärt und übersetzt. Verschiedene Stings mit verschiedenen Mutex zu schützen geht also normalerweise NICHT.
Nebenbei gilt dies nicht nur für Stringvariablen, sondern alle funktionen die strings auf irgendeine weise nutzen.

Es müssen also klar gesagt entweder die Compileroption "threadsafe" genutzt werden oder ALLE Strings (und Funktione und Befehel mit Strings) in ALLEN thread UND dem Hauptcode durch den selben Mutex geschützt werden. nur einmal vergessen und schon ist das Programm fehlerhaft.

Toshy
1. Win10
PB6.1
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

Jo, soweit sind wir ja dann auch gekommen. ^^
Nur "natürlich" ist das nicht. Man muss dafür schon wissen das PB ein etwas komplexeres Stringhandling hat als einfach nur Speicher zu allokieren und String reinzuschreiben. :wink:
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

Toshy hat geschrieben:So wurde es auf jedenfall mal von Fred erklärt und übersetzt.
Hm, warum hab ich das damals nicht gelesen? /:->
Hat irgend wer noch im Hinterkopf, wo Fred das mal so erklärt hat und den
Link parat? :D

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Beitrag von helpy »

PMV hat geschrieben:
Toshy hat geschrieben:So wurde es auf jedenfall mal von Fred erklärt und übersetzt.
Hm, warum hab ich das damals nicht gelesen? /:->
Hat irgend wer noch im Hinterkopf, wo Fred das mal so erklärt hat und den
Link parat? :D

MFG PMV
Das würde mich auch interessieren
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

er hat soweit ich weis nicht genau erklärt wie er es macht, sondern daß die Verwaltung auf eine Art strukturiert ist, bei man auf genau das achten muß.

Und in euren Beiträgen hat bisher keiner aufgeklärt, das man mit einem Mutex die gestammte Stringverwaltung schützen muß und nicht nur einzelen Strings.

So wäre laut bisherigen Erkärungen von der PB-Entwicklerseite (Fred & Co.) der folgende fehlerhaft. Der Code außerhalb des Strings nutzt nicht die selben Variablen, würde aber wenn die schleifen dauerhaft laufen irgendwann einen Programmabsturtz oder andere Fehler auslösen.
Viele Denken, es reicht wenn man die einzelnen Strings mit jeweils anderen Mutexen schützt oder normale Stringfunktionen und Befehle die nur in einer Zeile ich sage mal "was senden" nicht schützen muß.
Kurz gesagt, muß jeder wissen der Threads nutzt, aber nicht threadsafe einstellt, daß Jeder Codeteil (Stringzuweisungen, Befehele, Funktionen oder wie man es nennt) im gesammten Programm durch geschützt werden muß und zwar immer durch den selben Mutex.

Code: Alles auswählen

; Starten Sie diesen Code so wie er ist. Sie werden sehen, das die Zeilen
  ; gemischt durch die Threads ausgegeben werden. Jetzt entfernen Sie den
  ; Kommentar vor den Mutex-Befehlen und die Strings werden in Reihenfolge
  ; ausgegeben, da nur ein Thread zur gleichen Zeit das Recht zum Ausführen
  ; der Print-Befehle bekommt.
  ;
  Procedure WithoutMutex(*Number)     
    Shared Mutex
   
    For a = 1 To 50     
      ;LockMutex(Mutex)    ; entfernen Sie das ';' um den Unterschied zu sehen
   
      PrintN("Thread "+Str(*Number)+": Trying to print 5x in a row:")
      For b = 1 To 50
        Delay(5)
        PrintN("Thread "+Str(*Number)+" Line "+Str(b))
      Next b         
     
      ;UnlockMutex(Mutex) ; entfernen Sie das ';' um den Unterschied zu sehen
    Next a   
  EndProcedure
 
  OpenConsole()
  Mutex = CreateMutex()
 
  thread1 = CreateThread(@WithoutMutex(), 1)
  Delay(25)
  thread2 = CreateThread(@WithoutMutex(), 2)
  Delay(25)
  thread3 = CreateThread(@WithoutMutex(), 3)

      For b = 1 To 50
   PrintN("blabla")
test.s= "bla"
        Delay(5)
      Next b    


  WaitThread(thread1)
  WaitThread(thread2)
  WaitThread(thread3)
  
1. Win10
PB6.1
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

Wir haben dich schon verstanden ...

... und ich glaub dir auch in so weit, dass du recht haben könntest ...
... nur ohne es selber zu lesen werde ich meine Programme nicht ändern,
das würde schließlich unmengen an Arbeit machen ... bzw. müsste ich
dann doch Threadsafe verwenden ...

Ich nutz es schon seit langer Zeit genau so und habe bis heute keinen
absturz gehabt, den ich nicht am ende doch auf einen Fehler von mir
zurückführen konnte. Außer dem schon mal erwähnten Absturz auf Intel-
CPUs. War sicher im englischen Forum, oder? Werd ich wohl heut
nachmittag mal dannach suchen.

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 »

Ich weiß es auch nicht mehr. Kann in diesem oder jenem Forum gewesen sein oder ne direkte Kommunikation. Ich glaube er heißt Andre, ich bat ihn damals soweit ich mich erinnere mal bei Fred genauer nachzuhaken. Kann aber auch wer andere gewesen sein (wegen meiner Fehlenden Sprachkenntnisse).

Aber selbst die Hilfe impliziert das.
Zitat:
aber nicht empfehlenswert, da selbst eine einfache Sache wie der lokale Zugriff auf Strings gefhrlich sein kann und geschtzt werden muss.
Der lokale Zugriff kann ja nur dann in Thread gefährlich sein, wenn die Stringverwaltung durcheinander kommen kann.
Wann und wie ein Fehler auftreten kann weiß ich nicht. Nur wurde es halt mal so erklärt. Aber wer weiß schon was intern abläuft und ob Fred nicht nachträg die struktur verändert, damit das irgendwann gar nicht mehr vorkommen kann.[/quote]
1. Win10
PB6.1
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

Toshy hat geschrieben: Und in euren Beiträgen hat bisher keiner aufgeklärt, das man mit einem Mutex die gestammte Stringverwaltung schützen muß und nicht nur einzelen Strings.
Jo haben dich schon verstanden. Und sind wie gesagt auch schon so weit gekommen. Aber schön das du das nochmal bestätigst. :)
HeX0R hat geschrieben: Offensichtlich musst du dann alle deine Stringoperationen, egal ob im Thread oder ausserhalb, via Mutex abkapseln.
Wohl wegen dem hier
Thorium hat geschrieben: Dann greift PB intern auf irgendwas mehrfach gleichzeitig zu
Nur, ob das dann im Endeffekt performanter als die Threadsavevariante ist, ist fraglich.
Thorium hat geschrieben:Irgendwo wurde mal geschrieben das PB einen Stringpool verwendet. Hängt warscheinlich damit zusammen. Das Delay sorgt ganz einfach dafür, das die String-Operation "Protected HighScore$ = MyFunction(1,20)" schon abgearbeitet werden kann, bevor die andere Stringoperation durchgeführt wird "TempDir$ = GetTemporaryDirectory()". Von daher schon logisch nachvollziehbar.

Ich würde jetzt mal sagen man kommt garnicht an Threadsave vorbei, wenn man innerhalb der Threads Strings verwenden möchte.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

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

Beitrag von helpy »

Es gibt einen interessanten Beitrag von FR34K. Ein Zitat aus diesem Beitrag:
So the rule for the PB commandset is:

With threadsave mode on all the commands are threadsafe as long as they are used on resources local to the thread.

As soon as something shared is used, there needs to be a protection. (except for some simpler commands, but its generally better to protect everything)
cu guido
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

@helpy
Der Beitrag ist garnicht so interessant ... schließlich wird da nicht über die
Stringverwaltung gesprochen, sondern darüber, dass Befehle
normalerweise mehr als nur eine Anweisung ausführen und deswegen für
gleiche Objekte gesichert werden müssen. Eben so, wie wir es bis jetzt
machen. Der Sonderfall String ist dort leider nicht aufgeführt.

Toshy, die Hilfe ist nicht immer Maß der Dinge bzw. sind dort überall, wo
es probleme geben kann, entsprechende Hinweise eingebaut ... wenn aber
wir nicht zu denen gehören, die diese Dinge nutzen können, für wen sind
die dann? :lol:

Ich hab nun ein wenig gesucht ... erst im englischen, dann im deutschen
Forum ... Aussagen von Fred, Freak oder Andre hab ich bisher nicht
gefunden ... eventuell such ich nachher noch mal weiter. Gefunden habe
ich aktuell nur eine Aussage von NicTheQuick diesbezüglich:
http://www.purebasic.fr/german/viewtopi ... torder=asc
Interessant ist aber, das sein Beispiel auch bei ihm funktioniert, es also
eben nicht das von dir, Toshy angesprochende Problem gibt. Ich hab mir
nun ein eigenen Test geschrieben, der das Problem aufzeigen sollte:

Code: Alles auswählen

Global EndThread.l

#ThreadNumber = 100


Procedure Thread(Dumm.l)
  Protected String.s = "Dies ist ein unsichtbarer Lauftext"
  
  Repeat
    String = Right(String, 1) + Left(String, Len(String) - 1)
    Delay(1)
  Until EndThread
EndProcedure



Dim ID.l(#ThreadNumber - 1)
Define i.l
For i = 0 To #ThreadNumber - 1
  ID(i) = CreateThread(@Thread(), 0)
Next

MessageRequester("Threadtest", "Drücke OK um test zu beenden")
EndThread = #True
For i = 0 To #ThreadNumber - 1
  WaitThread(ID(i))
Next
MessageRequester("Threadtest", "Test erfolgreich beendet")
Läuft bei mir nun im Hintergrundm, ohne Threadsafe ... bisher keine
Abstürze ... ich denke 1 Stunde wird reichen. ... sollte das Programm
abstürzen, sag ich bescheid :wink:
Ach ja ... 1000 Threads funktionieren auch, dann ist die CPU-Auslastung
trotz des Delay(1) aber 100% und das erstellen der Threads dauert was
länger ... 100 denk ich mal sollten aber reichen :wink:

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Antworten