Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Was ist threadsicher? (https://www.delphipraxis.net/95815-ist-threadsicher.html)

Codewalker 13. Jul 2007 14:56


Was ist threadsicher?
 
Hallo liebe Wissenden.

Ich bin bisher immer ganz gut ohne das Wissen um Threads ausgekommen, aber bei der Programmierung mit Sockets kommt man da nicht drum herum. Dabei habe ich an einigen Stellen die Aufgabe (laut Delphi-Hilfe), Ereignis-Handler threadsicher zu programmieren. Was genau bedeutet threadsicher und worauf muss man da aufpassen?

Phoenix 13. Jul 2007 14:59

Re: Was ist threadsicher?
 
Beispiel:
Thread1 beginnt, in den Speicher zu schreiben
Thread1 wird unterbrochen
Thread2 läuft an
Thread2 liest den halb beschriebenen Speicher -> Datenmüll
Thread2 wird unterbrochen
Thread1 läuft an
Thread1 schreibt die restlichen Daten

Threadsicher heisst, dass es Dir bei einer solchen Klasse nicht passieren kann, dass ein Thread lesend auf einen Speicherbereich zugreift, während ein anderer Thread gleichzeitig etwas hineinschreibt. Das oben genannte Beispiel kann Dir also mit threadsicheren Klassen nicht passieren, da hier die Speicherzugriffe z.B. mit Critical Sections gekaspelt sind.

messie 13. Jul 2007 15:43

Re: Was ist threadsicher?
 
Zitat:

Zitat von Phoenix
Threadsicher heisst, dass es Dir bei einer solchen Klasse nicht passieren kann, dass ein Thread lesend auf einen Speicherbereich zugreift, während ein anderer Thread gleichzeitig etwas hineinschreibt.

Ist es also möglich, aus mehreren Threads gleichzeitig lesend auf denselben Speicherbereich zuzugreifen ohne das abzusichern?

Grüße, Messie

SirThornberry 13. Jul 2007 15:45

Re: Was ist threadsicher?
 
naja, nicht ganz. Der Arbeitsspeicher kann natürlich nur einwas gleichzeitig machen. Aber ansich können 2 threads schon gleichzeitig vom gleichen Speicherbereich lesen.

Olli 13. Jul 2007 15:45

Re: Was ist threadsicher?
 
Zitat:

Zitat von messie
Zitat:

Zitat von Phoenix
Threadsicher heisst, dass es Dir bei einer solchen Klasse nicht passieren kann, dass ein Thread lesend auf einen Speicherbereich zugreift, während ein anderer Thread gleichzeitig etwas hineinschreibt.

Ist es also möglich, aus mehreren Threads gleichzeitig lesend auf denselben Speicherbereich zuzugreifen ohne das abzusichern?

Moeglich schon, aber sobald du keine Mechanismen zum Absichern benutzt, koennte es sein, dass jeder Thread was anderes zu sehen bekommt, weil sich zwischendurch was geaendert hat. Wenn du also das Lesen nicht in deine Gleichung einbeziehst, koennten die Ergebnisse ziemlich inkonsistent werden.

Codewalker 13. Jul 2007 16:31

Re: Was ist threadsicher?
 
Okay, das Prinzip/Problem hab ich verstanden, ist ja fast logisch. Kennt ihr denn einen guten Einstieg (Anleitung/Tutorial) dazu, weil ich mich halt noch nie mit derartigen Problemen und Strukturen (z.B. Critical Sections) beschäftigt habe.

wicht 13. Jul 2007 16:45

Re: Was ist threadsicher?
 
Es gibt dazu Tutorials. Da solltest Du einfach mal googeln.. Sorry, scheiß Antwort :-D

Naja, aber der Ablauf ist eigentlich einfach.
Du erstellst zwei Threads, und gibts beiden als Eigenschaft oder direkt im Konstruktor eine Instanz einer Klasse mit, zum Beispiel TFileWriter. Diese Instanz wurde erstellt bevor die Threads erstellt wurden, logisch, und beide Threads kennen dann das selbe TFileWriter-Objekt. TFileWriter hat eine Prozedur SchreibeDaten(Daten: Typ), damit können die Threads Daten irgendwo hinschreiben, sagen wir halt in eine Datei. Beide Threads machen irgendwas und schreiben einfach Sachen indem Sie TFileWriter.SchreibeSachen(MeineDaten) aufrufen. Um das vernünftig zu machen, hat die Klasse TFileWriter (oder die Prozedur SchreibeDaten()) eine Instanz von TCriticalSection. Die erstellst du im Konstruktor der Klasse TFileWriter (oder halt ganz oben in der Prozedur..). Oben in SchreibeDaten() ist ein CritSect.Enter und ganz unten ein CritSect.Leave. Wenn jetzt ein Thread mit der Prozedur was schreiben möchte, aber der andere schon drin ist und dabei unterbrochen wurde, wartet der Thread, der schreiben möchte so lange, bis der andere aufgehört hat zu schreiben.. So kommen die Daten immer so an, wie man es geplant hat.
Vielleicht ist das Beispiel etwas komisch, aber so funktioniert es (wenn nicht, klärt mich auf!).

Also, vielleicht nochmal ein wenig googeln noch, und schau dir auch mal die Methode Synchronize() an. Die braucht man auch des öfteren, wenn man mit Threads am dölmern ist..

Viel Erfolg! :stupid:

Olli 13. Jul 2007 18:10

Re: Was ist threadsicher?
 
Ich kann von der Benutzung der Delphi TThread-Klasse und der Synchronize-Methode eigentlich nur abraten.

Luckie 13. Jul 2007 19:18

Re: Was ist threadsicher?
 
Turorial gibt s hier: http://delphitutorials.michael-puff.de

Phoenix 13. Jul 2007 21:31

Re: Was ist threadsicher?
 
Zitat:

Zitat von messie
Ist es also möglich, aus mehreren Threads gleichzeitig lesend auf denselben Speicherbereich zuzugreifen ohne das abzusichern?

Klar. Nur lesen ist bei sowas nie ein Problem. Problematisch wird es erst, wenn dort geschrieben wird.

boserPascal 13. Jul 2007 23:19

Re: Was ist threadsicher?
 
Allgemein regelt man dies über Semaphore. Das heißt du zählst eine Zahl beim Schreibzugriff hoch und wenn du fertig bist wieder runter. Geschrieben darf nun nur werden wenn Die Zahl Null ist, dh keine Lesezugriffe stattfinden. Du mußt also nur sicherstellen können, dass es zu Zeitfenster zum Schreiben kommt.

Gruß Stefan!

DGL-luke 14. Jul 2007 00:17

Re: Was ist threadsicher?
 
Critical Sections eignen sich meistens auch. Ein Semaphore ist insbesondere dann nützlich, wenn... ne. Ein Semaphore ist bei sowas eigentlich gar nicht nützlicher als eine Critical Section, es sei denn, man will eine Warteschlange einrichten.

Oder?

messie 14. Jul 2007 07:31

Re: Was ist threadsicher?
 
Zitat:

Zitat von Olli
Ich kann von der Benutzung der Delphi TThread-Klasse und der Synchronize-Methode eigentlich nur abraten.

Dann sag mal in ein paar Worten, warum und was Du stattdessen bevorzugst oder empfiehlst.

@Codewalker Ich nehme zum Synchronisieren Mutexe, da kannst Du mal in der Hilfe nachschauen. Finde ich übersichtlicher als die anderen Methoden.

Grüße, Messie

Phoenix 14. Jul 2007 08:47

Re: Was ist threadsicher?
 
Zitat:

Zitat von messie
@Codewalker Ich nehme zum Synchronisieren Mutexe, da kannst Du mal in der Hilfe nachschauen. Finde ich übersichtlicher als die anderen Methoden.

:shock: Zurück in die Ausbildung!
Das Verfahren nennt sich Mutex (Mutual Exclusion / Wechselseitiger Ausschluss) und wird entweder mit (ggf. binären) Semaphoren, dazu zählen auch die Monitore, oder mit Locks implementiert. Der Codeteil, der durch einen Mutext geschützt ist, ist die Critical Section.

Also bitte nicht durcheinander würfeln.

Olli 14. Jul 2007 12:20

Re: Was ist threadsicher?
 
Zitat:

Zitat von Phoenix
Zitat:

Zitat von messie
Ist es also möglich, aus mehreren Threads gleichzeitig lesend auf denselben Speicherbereich zuzugreifen ohne das abzusichern?

Klar. Nur lesen ist bei sowas nie ein Problem. Problematisch wird es erst, wenn dort zeitgleich geschrieben wird.

Ich habe da mal eine kleine Einfügung vorgenommen :mrgreen: :zwinker:

Atomische Operationen sind eigentlich nur bei einer Interlocked-Operation gegeben, bei Nicht-SMP/Nicht-Multicore aber theoretisch auch bei einfachen Operationen bis zur Standard-Wortbreite der CPU.

Zitat:

Zitat von messie
Zitat:

Zitat von Olli
Ich kann von der Benutzung der Delphi TThread-Klasse und der Synchronize-Methode eigentlich nur abraten.

Dann sag mal in ein paar Worten, warum und was Du stattdessen bevorzugst oder empfiehlst.

Direkt über die Win32-API gehen, oder eine eigene Threadklasse. Durch die Tatsache, daß viele Delphianer immer mehr zu Benutzern (von fertigen Komponenten/Klassen) verkommen statt zu Programmierern zu reifen, ist es scheinbar irrelevant geworden, was in der Doku zum Thema Synchronize steht/stand. Denn die Nachteile sind hinreichend dokumentiert. Ich zitiere mal aus der BDS2006-Hilfe:

Zitat:

Synchronize (private) Executes a method call within the main thread.
Wenn alles in Synchronize nicht mehr in dem Thread ausgeführt wird der durch die TThread-Instanz repräsentiert wird, dürfte jedem hier einleuchten was die übermäßige Benutzung dieser (IMO völlig falsch benannten) Methode bringt, nämlich das gleiche wie die Nicht-Benutzung von Threads. Habe es viel zu oft in Beispielcode innerhalb der Delphi-Community gesehen wie diese Klasse komplett falsch benutzt wird, daher die o.g. Einstellung.

wicht 14. Jul 2007 13:08

Re: Was ist threadsicher?
 
Klar, mitdenken muss man schon. Ständig im Thread Synchronize benutzen ist in der Tat unsinning, aber wenn man alle Paar Sekunden Informationen an den Hauptthread übergeben möchte, klappt das doch?
Wie machst du es denn, wenn du kein Synchronize benutzt?

Olli 14. Jul 2007 14:01

Re: Was ist threadsicher?
 
Zitat:

Zitat von wicht
Wie machst du es denn, wenn du kein Synchronize benutzt?

Ganz einfach, ich überlege mir welche Daten ich übergeben muß. Meistens ist das keine Unmenge und man kommt schon mit einer Fensternachricht an den Hauptthread klar. Ansonsten implementiere ich Locking. Aber im Großen und Ganzen umgehe ich eit Jahren Synchronize indem ich kein Delphi mehr für meine Hauptaufgaben benutze :mrgreen:

Anderes Beispiel: nähmen wir an jemand solle ein Array erstellen und mit Werten füllen. Das Erstellen kann im Hauptthread erfolgen, aber da die Werte bspw. über das Netzwerk angefragt werden, dauert das länger, weshalb man sich entscheidet einen Thread für jeden zu füllenden Wert zu erstellen (kann ja auch nacheinander geschehen um die Auswirkung von Timeouts zu vermindern, es müssen also nicht genausoviele Threads wie Werte existieren). Der Thread bekommt dann die Adresse des zu füllenden Wertes mit und beschreibt die unter Verwendung eines Locks (bei "viel" Daten) oder einer Interlocked-Operation bei einem kleinen Datum.

Rollo62 4. Aug 2015 11:48

AW: Was ist threadsicher?
 
Hallo Olli,

ich benutze Locks wenn ich Variablen Schreibend/Lesend austauschen möchte,
und Syncronize wenn ich mal eine Message an den Hauptthread absenden muss.

Ganz verteufeln würde ich Syncronize nicht, denn im Prinzip macht es doch
auch nur intern was man sonst von Hand schreiben müsste.
Ich gebe aber zu das ich mir die Implementierung von Synchronize noch nicht angesehen haben.

Und es gibt auch noch Queue, hälst du davon dann auch nichts ?

Einen Riesenvorteil gegenüber deiner Win.Thread.Create Lösung sehe ich in der Platformunabhängigkeit.
Das möchte ich wirklich nicht auf allen Platformen von Hand optimieren.

Rollo

Mavarik 4. Aug 2015 12:11

AW: Re: Was ist threadsicher?
 
Zitat:

Zitat von Olli (Beitrag 650518)
Meistens ist das keine Unmenge und man kommt schon mit einer Fensternachricht an den Hauptthread klar. Ansonsten implementiere ich Locking. Aber im Großen und Ganzen umgehe ich eit Jahren Synchronize indem ich kein Delphi mehr für meine Hauptaufgaben benutze :mrgreen:

Egal wie Du es nennst... Ob Synchronize oder ob Du es Windows überläßt... Weil was macht den Windows?
Eine Fensternachricht ist nahezu nix anderes als ein Commandpool der dann synchronisiert wird...

Naja und dann funktioniert es nur unter Windows... Das will doch keiner mehr...8-)

Synchrinize oder Queue sind die richtigen Wege um die GUI upzudaten... Kommt immer darauf an, ob ich dafür den Thread "anhalten" will oder nicht.

Ich gebe Dir Recht, dass in vielen Beispielen Threads mit GUI verbunden wird, aber das ist doch eher zur Demonstration - damit am sieht was ein Thread macht...

Der Trick an Threads eigentlich anders herum... Soviel wie möglich CPU-Zeit für den MainThread bereit zu stellen, damit der Bildschirm reaktiv bleibt...

Sir Rufo 4. Aug 2015 12:14

AW: Was ist threadsicher?
 
Ob der Olli überhaupt noch antworten wird? (Beitrag von 2007 und der UserAccount ist gelöscht) :stupid:

Mavarik 4. Aug 2015 12:16

AW: Was ist threadsicher?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1310930)
Ob der Olli überhaupt noch antworten wird? (Beitrag von 2007 und der UserAccount ist gelöscht) :stupid:

Sack Reis... Hauptsache andere lesen es...

Rollo62 4. Aug 2015 23:45

AW: Was ist threadsicher?
 
Naja, bei mir wars als neu markiert ??!!

Stevie 5. Aug 2015 06:41

AW: Was ist threadsicher?
 
What is this thing you call "thread safe"?

Mavarik 5. Aug 2015 08:44

AW: Was ist threadsicher?
 
Zitat:

Zitat von Stevie (Beitrag 1311052)

Reichlich eng beleuchteter Sonderfall...

Richtig ist natürlich, dass wenn A Thread-Safe ist und B es benutzt, B noch lange nicht Thread-Safe seinen muss...

Bei der Thread-Safe-Frage geht es doch aber i.d.R. um zwei Dinge...

1. Wie muss ich meinen Thread-Code bauen, damit ich Ihn von mehreren Seiten oder in einem Thread benutzen kann.
2. Ist die XY Routine oder das XY Object aus der RTL Thread-Safe oder reentrant.

Mavarik

Stevie 5. Aug 2015 09:12

AW: Was ist threadsicher?
 
Zitat:

Zitat von Mavarik (Beitrag 1311082)
Reichlich eng beleuchteter Sonderfall...

...

Bei der Thread-Safe-Frage geht es doch aber i.d.R. um zwei Dinge...

Nicht wirklich ein Sonderfall.

Frag dich mal, warum immutables und funktionale Programmierung so gut für Concurrency funktioniert:
weil es dort keinen shared state gibt, um den man sich sorgen muss.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz