Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“ (https://www.delphipraxis.net/180940-die-frage-aller-fragen-sammlung-%84ist-das-thread-safe-%93.html)

Mavarik 2. Jul 2014 01:55


Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Hallo Zusammen!

Ich glaube Jeremy North hat mal geschrieben: „Wenn ich für jede Frage: „Ist das Thread-Safe“, einen Dollar bekommen würde, bräuchte ich nicht mehr zu arbeiten“ (frei übersetzt)…

Ich möchte hier mal diesen Diskussion-Thread :lol: starten um die häufigsten Frage und Antworten zu sammeln.

Was bedeutet eigentlich Thread-Safe?

Oder müsste die eigentliche Frage lautet: „Ist xy reentrant?“

Also was darf ich in einen Thread machen und was nicht und wann brauche ich ein Syncronize?

Wenn man(n) nach Thread safe googled oder auch DP’ed bekommt man schon unzählige Antworten. Jedoch beantworten 99 von 100 Suchergebnissen nicht den „eigentlichen“ Kern der Frage, oder?

Was ist den Atomar?
Wann brauche ich ein critical section?
Wann brauche ich eine Semaphore?
Oder reicht mir ein Spinlock?

Sicherlich gibt es hierzu Tutorials. Zum Beispiel hier!

Besonders bemerkenswert ist hieraus folgenden Satz:

Zitat:

Zitat von Lossy eX
Und wenn man alles synchronisiert, dann kann man auch komplett auf den Thread verzichten. Weil dadurch alles im VCL-Thread ausgeführt wird. Und das ist ja eigentlich nicht Sinn und Zweck davon

Ich kenne „nur“ die Aussage die VCL ist nicht Thread safe! FMX „wahrscheinlich“ auch nicht.
Das lassen wir einfach mal so stehen. Aber ist die VCL/FMX reentrant?

Reden wir hierbei von den Komponenten oder über die Systemroutinen?
Was gehört zu dieser VCL Aussage?

Was ist mit einem lesenden Zugriff in einem Thread nach dem Motto:

Delphi-Quellcode:
procedure TMyThread.Execute;
var
  S : String;
begin
  while not(Terminated) do
  begin
    S := Edit10.Text;
    Foo(S);
  End;
end;
Brauche ich für den Zugriff auf Edit10.Text ein Syncronize?
Was kann passieren?

OK, nochmal zurück zum Grund der Frage.

Warum möchte man überhaupt einen Thread erzeugen?

a.) Eine Verarbeitung soll parallel laufen oder im Hintergrund
b.) Die Software soll schneller werden.
c.) ??

Erst mal zu b.

Zitat:

Zitat von Physikalischer Ausflug
Beim aktuellen Stand der Technik ist die Taktrate der CPU - auf Grund der Lichtgeschwindigkeit und der sich daraus ergebenden Strecken die vom Strom zurückgelegt werden können - beschränkt und es ist ein Ende erreicht/in Sicht..
Wenn nicht alles noch kleiner wird müssen andere Techniken her, denn teilweise ist die Sperrschicht der Transistoren schon nur noch wenige Atome dick.

Ein Programm kann also nur schneller werden, wenn die Arbeit auf verschiedene Prozessor-Kerne ausgelagert wird.

Aber was will ich den beschleunigen?

Bei „normalen“ Programmen (was ist schon normal) wartet die Software zu 99,9% auf die Eingabe des Benutzers. Aber dann… Wenn der Benutzer eine Aktion ausführt soll es doch möglichst schnell gehen.
Es wurde dann immer gesagt: „Mach doch die komplizierte Berechnung in einem Thread!“

Was ist den eine komplizierte Berechnung und woher kommen die Daten? Wir reden ja nicht davon Pi auf 1000 Stellen zu berechnen, sondern eher von 3*7+StrtoInt(Edit10.Text) + 19% MwSt. Summe(SQL-Table)… Aber genau da kommen wir zu „unserem“ Punkt.

Können 2 Thread’s StrtoInt aufrufen? Was ist mit einer SQL-Abfrage? Dateioperationen? Drucker Zugriff?

Ich könnte mir vorstellen, dass eine TTable die auf ein Formular geklickt wurde „schlecht ist um in einem Thread benutzt zu werden, aber was ist wenn ich diese im Thread lokal erzeuge?

Gibt es System Routinen die nicht gleichzeitig von mehreren Thread aus aufgerufen werden dürfen?
Was ist mit den Indy-Routinen? Ich nutze gerne einen Thread für http oder SOAP Requests. Funktioniert prima… Aber das gehört eher zu (a)

Wie lange muss meine Routine eigentlich dauern, damit es sich lohnt diese in einen Thread aus zu lagern?
Das erzeugen des Thread’s mit kompletten overhead kostet ja auch Zeit. Also für die 10 Fälle wo ich einen Thread brauche diesen schon beim Programmstart erzeugen? Kann ich das erzeugen der Threads in einen Thread auslagern? :-)

Nutzt mir hier ein ThreadPool?

Benötige ich meinen Thread immer wieder, füttere ich „Ihn“ also nur mit neuen Daten und setze einen Event? Oder erzeuge ich den Thread jedes mal neu?

Wie ist denn meine Aufgabenstellung?

Fragen über Fragen und dann noch die Unsicherheit ob das alles so Safe ist… oder ob ich mir Deadlocks erzeuge…

Kommen wir mal zurück zu Punkt (a)
Schön ist es wenn ich eine Verarbeitung in einen Thread auslagern kann, dieser Thread dann - wenn er fertig ist - eine Procedure aufruft, die dann das Ergebnis verarbeiten kann. (Idealfall)

Was ist aber wenn ich auf das Ergebnis warten muss?

Beispiel:
Ich habe eine http Request und will das den erhaltenen content dann verarbeiten. Solange ich nicht das Ergebnis in meinem Workflow brauche, sondern die Inhalte nur gespeichert werden sollen. Prima, aber was wenn der User damit etwas machen soll?

Ich starte also den Thread für den Request… Mache „schnell“ noch was anderes im Vordergrund task und dann? Muss ich auf das Ergebnis warten, oder ist es schon da? Das hängt natürlich von der Internet und CPU Geschwindigkeit ab. Diese also dann vorher testen und dann entscheiden ob Thread oder nicht?

Ich denke es gibt hier noch genügend Fragen die noch zu beleuchten sind. Auch weil die Thread Implementierung von Delphi zu Delphi Version immer „besser“ geworden ist.

Wie sind Eure Erfahrungen?
Wie häufig nutzt Ihr Threads und wo für?
Soll man eine Library nehmen oder von Fall zu Fall den Thread neu programmieren?
Wie sieht es auf anderen Plattformen aus? Android/iOS/Mac…

Lasst und mal sammeln…

Grüsse Mavarik

PS.: Die Intention dieses Threads 8-) ist eine Sammlung für alle interessierten zu zentralisieren. Die Aufgestellten Fragen sind nicht meine (naja vielleicht ein/zwei davon schon) :stupid:

Stevie 2. Jul 2014 07:02

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Save?“
 
Bei dem Titel fiel mir direkt dieser Artikel ein:
What is this thing you call "thread safe"?

Sherlock 2. Jul 2014 07:04

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Save?“
 
OT:
Und du hast nur die Spitze des Eisbergs gesehen, Google mal nach "thread safe". Da kippste um!

Sherlock
-dem man so früh am Morgen den Rechtschreib-Flame verzeihen möge

Mavarik 2. Jul 2014 09:22

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Save?“
 
Zitat:

Zitat von Sherlock (Beitrag 1264025)
OT:
Und du hast nur die Spitze des Eisbergs gesehen, Google mal nach "thread safe". Da kippste um!

Aber hilft das? Oh ja verstehe...
Aber wenigstens konsequent durchgesetzt...

Zitat:

Zitat von Stevie (Beitrag 1264024)
Bei dem Titel fiel mir direkt dieser Artikel ein:
What is this thing you call "thread safe"?

OK kannte ich nicht...

Dejan Vu 2. Jul 2014 09:37

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Ich glaube, 'ist das threadsafe' kann man sich anhand der Definition im Wiki selbst beantworten.
Die Frage lautet, wann setzt man Threads sinnvoll ein?

Mir fallen drei Szenarien ein:
  1. Viele Aktionen werden in einer Schleife abgearbeitet. Die GUI soll dabei aus ästhetischen Gründen nicht blockiert werden, die Schleife soll man aber abbrechen können. Das geht hemdsärmelig mit 'Application.ProcessMessages', aber ein Thread ist eleganter (Background Thread).
  2. Einkommende Aufträge sollen abgearbeitet werden. Der Empfang einkommender Aufträge darf nicht blockiert werden. (Workerthread mit Queue, Overlapped Execution).
  3. Viele voneinander unabhängige Aktionen müssen in möglichst kurzer Zeit durchgeführt werden (Parallele Threads)
Natürlich gibt es noch mehr Szenarien, Mischformen und Ausprägungen dieser Grundprobleme.

p80286 2. Jul 2014 10:41

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Save?“
 
Zitat:

Zitat von Stevie (Beitrag 1264024)
Bei dem Titel fiel mir direkt dieser Artikel ein:
What is this thing you call "thread safe"?

Nach der Lektüre kann ich Mavarik gut verstehen.

Gruß
K-H

BUG 2. Jul 2014 19:57

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Mavarik (Beitrag 1264017)
Oder reicht mir ein Spinlock?

Das riecht irgendwie nach Ärger: Synchronisationsmittel nicht selbst implementieren. Das Konzept klingt einfach, aber es gibt einige Tücken. Sperr-Synchronisation ist auf höherer Ebene schwer genug ... da sollte sich der Anwendungsentwickler nicht noch mit den Caches rumschlagen.


Zitat:

Zitat von Mavarik (Beitrag 1264017)
Ich kenne „nur“ die Aussage die VCL ist nicht Thread safe! FMX „wahrscheinlich“ auch nicht.
Das lassen wir einfach mal so stehen. Aber ist die VCL/FMX reentrant?

Die beiden Konzepte sind orthogonal zueinander. Man kann eine reentrante API haben, die nicht tread-safe ist und umgekehrt. Unix-Betriebssystem-Aufrufe sind öfter beides. Allgemeine Bibliotheken sind meist beides nicht.


Zitat:

Zitat von Mavarik (Beitrag 1264017)
Fragen über Fragen und dann noch die Unsicherheit ob das alles so Safe ist… oder ob ich mir Deadlocks erzeuge…

Tja, mit den Deadlock-Freiheit ist das so eine Sache. Wenn man eine Lock-Hierarchy einhält oder zyklische Abhängigkeiten anderweitig vermeidet, mag man das noch beweisen können; ansonsten sieht es im Allgemeinen düster aus.

stoxx 2. Jul 2014 21:21

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Mavarik (Beitrag 1264017)
Hallo Zusammen!
Was ist den Atomar?
Wann brauche ich ein critical section?
Wann brauche ich eine Semaphore?
Oder reicht mir ein Spinlock?


Eine parallele Verarbeitung ist doch was schönes. Egal wie schnell eine einzige CPU noch werden kann.
Vielleicht existiert ja auch Software, die nicht nur auf simple Usereingaben wartet.


Zitat:

Zitat von Mavarik (Beitrag 1264017)
Hallo Zusammen!
Was ist den Atomar?

Atomar heißt, dass die CPU sicherstellt, dass ein Vorgang wirklich nacheinander, also serialisiert durchgeführt wird.
Wie im Wikipedia Artikel auch beschrieben, zieht das zwangsläufig ebenso nach sich, dass ein Thread oder nenn es auch "Vorgang" in seiner Arbeit für eine bestimmten Moment nicht unterbrochen werden darf (durch einen Interrupt)

Die Threadsicherheit geht je nach verwendeter CPU schon bei einem normalen Integer verloren. 4 Byte.
Zwei Threads arbeiten mit einer Integervariablen. Der eine schreibt gerade die erste Hälfte von den 4 Bytes, der andere Thread liest aber gerade in dem Moment die Integervariable. Du siehst, die Daten sind nicht die, die Du erwartest und schon gar nicht logisch richtig.
Ein Boolean ist wohl wirklich atomar Threadsicher.
Atomar bedeutet einfach, dass die Technick herum um die Software irgendwann nur noch die Threadsicherheit übernehmen kann. In dem Fall die CPU. Critical Sections selbst müssen atomar sein. In dem Fall vom Betriebssystem zur Verfügung gestellt.


Zitat:

Zitat von Mavarik (Beitrag 1264017)
Hallo Zusammen!
Wann brauche ich ein critical section?

immer sobald mehrere Threads mit Daten arbeiten, und einer davon schreibend auf Daten tätig ist.
Schon das Arbeiten mit einer Liste muss abgesichert werden.
If list.Count > 0 .. dann mache irgendwas, kann schon zu Programmabstürzen führen, wenn gerade in dem Moment ein anderer Thread was aus der Liste löschen würde, und bei der Abfrage: list.count noch ein Element drin ist, und dann beim Zugriff auf das Element es auf einmal gar nicht mehr da wäre.


Zitat:

Zitat von Mavarik (Beitrag 1264017)
Hallo Zusammen!
Wann brauche ich eine Semaphore?

Critical Sections funktionieren nicht Prozessübergreifend ... ein Semaphore oder Mutex bräuchtest Du beim gemeinsamen Zugriff zweier Programme auf eine Datei, auf gemeinsame Daten, auf gemeinsame Dinge...


Zitat:

Zitat von Mavarik (Beitrag 1264017)
Hallo Zusammen!
Oder reicht mir ein Spinlock?

Ein Spinlock ist nur ein Zusatzfeature einer Critical Section oder beliebigen Lock Methode.
Das Anhalten eines Threads mit einer Critical Section führt in hochperformanten Anwendungen zu Performance Verlusten.
Ein Spinlock lässt den zu wartenden Thread einfach ein paar Millisekunden im "Kreise" drehen, und wenn dann die Freigabe immer noch noch nicht erteilt ist, erst dann geht er in "Ruhezustand"..
Für all Deine beschriebenen Anwendungen, die nur auf "Usereingaben" warten ist das alles nicht relevant.
*smile*

Für nähere Infos siehe auch Microsofts "InitializeCriticalSectionAndSpinCount" function.

Allerdings sind Spinlocks bei Zugriff auf Daten von mehr als 2 Threads großer Mist und werden in der Praxis meiner Erfahrung nach etwas "hakelig". Manche Threads kommen dann gar nicht gleichranging zum Zug. Da ist die Betriebssysteminterne Verwaltung mit Critical Sections tausend Mal besser. Da gehts geordnet der Reihe nach, die Threads werden vom Betriebssystem in geordneter Reihenfogle aus dem Ruhezustand geholt.

Wenn man all seine Programme versteht, ist alles gar nicht so schwer ..
Ein sauberer modularer Programmierstil ist unerlässlich mit sauberen Schnittstellen nach außen...

Sir Rufo 2. Jul 2014 21:40

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
@stoxx

Wenn ein Integer nach deiner Darstellung nicht sicher ist, dann kann auch ein Boolean unsicher sein (hängt davon ab wie ein Boolean intern gespeichert/verarbeitet wird).

Bei 32bit werden allerdings - soweit mir bekannt - immer genau 4 Bytes (=32bit) bearbeitet, und deswegen ist ein 8/16/24/32bit-Wert auf einem 32bit-Betriebssystem threadsafe, denn die CPU lockt dafür den Speicherplatz (32bit) im Arbeitsspeicher.

Darum ist es ja auch ein 32bit-Betriebssystem, das eine 32bit CPU benötigt.
Darum sind 64bit-Programme teilweise langsamer, weil eben bei jedem Zugriff immer 64bit bewegt (doppelte Menge).
  • Arbeitet die Anwendung bevorzugt mit 32bit-Werten (z.B. Integer), dann wird das unter 64bit langsamer als unter 32bit.
  • Arbeitet die Anwendung bevorzugt mit 64bit-Werten (z.B. Int64, Cardinal), dann wird das unter 64bit schneller als unter 32bit.

Ehrlich gesagt würde ich aber selbst einen Zugriff auf einen Integer mit einem Lock absichern, bzw. eigentlich tausche ich fast immer komplexere Datenelemente mit einem Thread aus, wo alles enthalten ist um die Aufgabe zu erledigen. Mit nur einem Integer-Wert ist das eher selten möglich :)

stoxx 2. Jul 2014 22:06

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Sir Rufo (Beitrag 1264172)
@stoxx

Wenn ein Integer nach deiner Darstellung nicht sicher ist, dann kann auch ein Boolean unsicher sein (hängt davon ab wie ein Boolean intern gespeichert/verarbeitet wird).

>Edit< .. hab meinen vorigen Text nochmal editiert .. genau genommen trifft das in der Tat auch auf booleans zu.
Auch egal, wie er gespeichert, verarbeitet wird, nämlich immer dann, wenn der Wert geprüft wird, und dann vielleicht geändert.
(ist das gleiche Problem, wie unten mit dem increment vom Integer beschrieben)

Zitat:

Zitat von Sir Rufo (Beitrag 1264172)
@
Bei 32bit werden allerdings - soweit mir bekannt - immer genau 4 Bytes (=32bit) bearbeitet, und deswegen ist ein 8/16/24/32bit-Wert auf einem 32bit-Betriebssystem threadsafe, denn die CPU lockt dafür den Speicherplatz (32bit) im Arbeitsspeicher.


das hängt von der CPU ab.
Ein auf dem eigenem Rechner programmiertes und getestes Programm muss noch lange nicht stabil überall funktionieren.
So pauschal kann man das nicht sagen. Es hängt nicht vom Betriebssystem ab, sondern von der CPU (und vom Compiler) ..

Hier mal beispielhaft die Aussagen von Intel

https://software.intel.com/en-us/forums/topic/308940


ich hab auch irgendwo mal eine komplette umfangreiche Liste gefunden, ich werde mal suchen ...

Nicht atomar zu sein heißt ja auch, 2 Threads wollen einen Wert incrementieren.
Beide lesen den Wert 5, und schreiben (leider gleichzeitig) 6 hinein.
Wenn das beide gleichzeitig machen, steht am Ende 6 drin, obwohl 2 Threads zweimal hochgezählt haben und 7 drinstehen müsste.
Daher auch die existierende Windows Funktion InterlockedIncrement ....

stoxx 2. Jul 2014 23:14

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Sir Rufo (Beitrag 1264172)
@stoxx
Bei 32bit werden allerdings - soweit mir bekannt - immer genau 4 Bytes (=32bit) bearbeitet, und deswegen ist ein 8/16/24/32bit-Wert auf einem 32bit-Betriebssystem threadsafe, denn die CPU lockt dafür den Speicherplatz (32bit) im Arbeitsspeicher.

Also man stelle sich einfach mal 2 echte Prozessoren auf 2 Sockel auf einem Mainboard vor.
Mir ist nichts von einer Lockingmöglichkeit jeder einzelnen Zelle im Arbeitsspeicher bekannt.
Was meinst Du damit?

Ich kann Dir nur sagen, dass auf einem echten Dual XEON Server mit 2 echten CPU's alle Programmierfehler noch viel kritischer sind und zu lustigen Abstürzen führen können, was auf einem Single Socket Mainboard, selbst mit zig Cores noch problemos funktionieren kann.

Sir Rufo 2. Jul 2014 23:36

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von stoxx (Beitrag 1264176)
Zitat:

Zitat von Sir Rufo (Beitrag 1264172)
@stoxx
Bei 32bit werden allerdings - soweit mir bekannt - immer genau 4 Bytes (=32bit) bearbeitet, und deswegen ist ein 8/16/24/32bit-Wert auf einem 32bit-Betriebssystem threadsafe, denn die CPU lockt dafür den Speicherplatz (32bit) im Arbeitsspeicher.

Also man stelle sich einfach mal 2 echte Prozessoren auf 2 Sockel auf einem Mainboard vor.
Mir ist nichts von einer Lockingmöglichkeit jeder einzelnen Zelle im Arbeitsspeicher bekannt.
Was meinst Du damit?

Nun ich kann mir nicht vorstellen, 2-n echte Prozessoren es schaffen sollten ein und die selbe Speicheradresse im selben/gleichen Moment zu beschreiben. Kann eigentlich nicht möglich sein, denn dann müssten sich beide zur exakt selben Zeit auf dem Bus zum Speicher befinden ... wie soll das sinnvoll gehen?

Bei den aktuellen XEON-MultiCore-Boards hat übrigens jede CPU ihren eigenen Speicher.
Zitat:

Zitat von stoxx (Beitrag 1264176)
Ich kann Dir nur sagen, dass auf einem echten Dual XEON Server mit 2 echten CPU's alle Programmierfehler noch viel kritischer sind und zu lustigen Abstürzen führen können, was auf einem Single Socket Mainboard, selbst mit zig Cores noch problemos funktionieren kann.

Ist halt eine andere Liga :)

stoxx 2. Jul 2014 23:46

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Sir Rufo (Beitrag 1264179)
Nun ich kann mir nicht vorstellen, 2-n echte Prozessoren es schaffen sollten ein und die selbe Speicheradresse im selben/gleichen Moment zu beschreiben. Kann eigentlich nicht möglich sein, denn dann müssten sich beide zur exakt selben Zeit auf dem Bus zum Speicher befinden ... wie soll das sinnvoll gehen?

da bin ich technisch im Moment überfragt. Aber Du hast immer das Problem, dass 2 Threads eine Variable lesen können, eine gewisse Zeit damit was tun, und diese wieder zurückschreiben. Selbst wenn der Lese und Schreibvorgang nicht gleichzeitig erfolgt, kann die Verarbeitung fast parallel verlaufen und logisch falsch sein. (Eben z.b. irgendwas hochzählen)
Ich hab da morgen nochmal einen schönen Link dazu mit Delphi Beispielsourecode.
Wenn man mit 2 Threads ungesichert eine gemeinsame Variable hochzählen lässt, und jeder Thread für sich auch nochmal zusätzlich einen Counter hochzählt, dann stimmt die Summe nicht überein mit der gemeinsam hochgezählten Variablen.

Zitat:

Zitat von Sir Rufo (Beitrag 1264179)
Bei den aktuellen XEON-MultiCore-Boards hat übrigens jede CPU ihren eigenen Speicher.

naja .. eine Variable, ein Speicher .. RAM gibts nur einmal ..
Ich meine ja nicht den Cache sondern den echten physischen RAM. (Als Riegel ;-) )


http://de.wikipedia.org/wiki/DDR-SDRAM

Sir Rufo 3. Jul 2014 00:05

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von stoxx (Beitrag 1264182)
Zitat:

Zitat von Sir Rufo (Beitrag 1264179)
Nun ich kann mir nicht vorstellen, 2-n echte Prozessoren es schaffen sollten ein und die selbe Speicheradresse im selben/gleichen Moment zu beschreiben. Kann eigentlich nicht möglich sein, denn dann müssten sich beide zur exakt selben Zeit auf dem Bus zum Speicher befinden ... wie soll das sinnvoll gehen?

da bin ich technisch im Moment überfragt. Aber Du hast immer das Problem, dass 2 Threads eine Variable lesen können, eine gewisse Zeit damit was tun, und diese wieder zurückschreiben. Selbst wenn der Lese und Schreibvorgang nicht gleichzeitig erfolgt, kann die Verarbeitung fast parallel verlaufen und logisch falsch sein. (Eben z.b. irgendwas hochzählen)
Ich hab da morgen nochmal einen schönen Link dazu mit Delphi Beispielsourecode.
Wenn man mit 2 Threads ungesichert eine gemeinsame Variable hochzählen lässt, und jeder Thread für sich auch nochmal zusätzlich einen Counter hochzählt, dann stimmt die Summe nicht überein mit der gemeinsam hochgezählten Variablen.

Da haben wir aber aneinander vorbeigeredet. Das ist ja auch logisch, denn ein Thread-Cycle ist nicht zwangsläufig gleich einem CPU-Cycle. Und wenn ich einen Wert aus dem Speicher lese, dann habe ich den Wert, den er zu diesem Zeitpunkt hatte, einen CPU-Zyklus später, kann das eben völlig anders sein. Dafür gibt es ja auch extra Delphi-Referenz durchsuchenInterlockedIncrement.

Es ist aber völlig unproblematisch auf einem 32bit-Betriebssystem einen 32bit-Wert in ein und dieselbe Speicherstelle mit mehreren Threads zu schreiben und auch zu lesen ohne einen Zugriffsfehler zu bekommen. Denn der Zugriff darauf erfolgt in einem Rutsch.
Zitat:

Zitat von stoxx (Beitrag 1264182)
Zitat:

Zitat von Sir Rufo (Beitrag 1264179)
Bei den aktuellen XEON-MultiCore-Boards hat übrigens jede CPU ihren eigenen Speicher.

naja .. eine Variable, ein Speicher .. RAM gibts nur einmal ..
Ich meine ja nicht den Cache sondern den echten physischen RAM. (Als Riegel ;-) )
http://de.wikipedia.org/wiki/DDR-SDRAM

Ich meine auch die Riegel und da hat jeder CPU-Klotz seine eigenen Riegel

BUG 3. Jul 2014 00:06

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von stoxx (Beitrag 1264176)
Mir ist nichts von einer Lockingmöglichkeit jeder einzelnen Zelle im Arbeitsspeicher bekannt.

Soweit ich weiß, sollte bis in die Caches hinein der Lock-Präfix funktionieren. Danach muss man sich eh mit Cache-Kohärenz herumschlagen.

Eigentlich bezweifle ich, dass man für die meisten Anwendungen wirklich in die Untiefen in der parallele Programmierung eintauchen muss. CriticalSections, Semaphoren, ReaderWriter und das Synchronize sollten für vieles ausreichen.


Zitat:

Zitat von Sir Rufo (Beitrag 1264179)
Kann eigentlich nicht möglich sein, denn dann müssten sich beide zur exakt selben Zeit auf dem Bus zum Speicher befinden ... wie soll das sinnvoll gehen?

Beide schreiben in ihren eigenen Cache (EDIT: beziehungsweise andere Puffer and Warteschlangen im Prozessor) und sehen zu dieser Zeit nicht die Änderungen, die der andere gemacht hat. Beide sehen nur ihre eigenen Änderungen, solange es nicht zwischendurch etwas wie mfence-Operationen gibt. Irgendwer "gewinnt" dann und bestimmt den physischen Stand im Hauptspeicher, aber dann ist der Schaden schon angerichtet.


Zitat:

Zitat von Sir Rufo (Beitrag 1264179)
Bei den aktuellen XEON-MultiCore-Boards hat übrigens jede CPU ihren eigenen Speicher.

Ich nehme mal an, das geht in Richtung NUMA-Architektur. Vielleicht hast du einen Link, wo das genauer beschrieben ist?


Viel cooler ist der transaktionale Speicher, den Intel in der Haswell-Generation eingeführt hat. Aber bis man darauf in Delphi zurückgreifen kann, vergehen vermutlich noch ein paar Dekaden.

Sir Rufo 3. Jul 2014 00:17

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von BUG (Beitrag 1264187)
Zitat:

Zitat von Sir Rufo (Beitrag 1264179)
Bei den aktuellen XEON-MultiCore-Boards hat übrigens jede CPU ihren eigenen Speicher.

Ich nehme mal an, das geht in Richtung NUMA-Architektur. Vielleicht hast du einen Link, wo das genauer beschrieben ist?

Hier auf Seite 22 (bzw. Seite 10)
Anhang 41397
intel 3.2.2.2 Memory Slot Identification and Population Rules (S.25)
  • The memory slots associated with a given processor are unavailable if the corresponding processor socket is not populated.
  • A processor may be installed without populating the associated memory slots provided a second processor is installed with associated memory. In this case, the memory is shared by the processors. However, the platform suffers performance degradation and latency due to the remote memory.

stahli 3. Jul 2014 12:01

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Gibt es eigentlich Prozesse, die Zugriffe nur bei schreibenden Zugriffen sperren?

CriticalSection.Enter verhindert ja (m.W.n) gleichzeitige lesende Zugriffe (z.B. 10 Zugriffe auf eine Liste). Stimmt das?

Dann wäre doch sinnvoll, z.B. 8 lesende Zugriffe mit
"CriticalSection.EnterRead" gleichzeitig zuzulassen und nur wenn dann ein "CriticalSection.EnterWrite" dazwischen kommen sollte die 8 Leseaktionen zu beenden, den Zugriff wirklich zu sperren und erst danach wieder andere Zugriffe zuzulassen.

Ist meine Überlegung sinnvoll? Oder gar schon so realisiert (in der Hilfe habe ich dazu nichts Genaues gefunden).

Dejan Vu 3. Jul 2014 12:19

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Critical Sections sorgen einfach dafür, das immer nur ein Thread beim Aufruf von 'Enter' sofort weiter macht. Bei allen anderen 'hängt' der Aufruf, bis der erste Thread (oder wer auch immer) das 'Leave' der CS Aufruf.

Der schöne Günther 3. Jul 2014 12:20

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Ich habe das Thema nur oberflächlich überflogen. Was ich kurz anmerken wollte:

Zitat:

Zitat von Sir Rufo (Beitrag 1264172)
Bei 32bit werden allerdings - soweit mir bekannt - immer genau 4 Bytes (=32bit) bearbeitet, und deswegen ist ein 8/16/24/32bit-Wert auf einem 32bit-Betriebssystem threadsafe, denn die CPU lockt dafür den Speicherplatz (32bit) im Arbeitsspeicher

Wenn ich das nicht falsch verstanden habe, muss man aber auch bei Pascal in einem Sonderfall aufpassen: Wenn der Integer in einem
Delphi-Quellcode:
packet record
steckt- Dann ist der doch nicht unbedingt so ausgerichtet dass die CPU den in einem Rutsch ins Register schaufelt und zwei Takte braucht.

Irgendwie sowas, oder?

stahli 3. Jul 2014 12:44

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Dejan Vu (Beitrag 1264261)
Critical Sections sorgen einfach dafür, das immer nur ein Thread beim Aufruf von 'Enter' sofort weiter macht. Bei allen anderen 'hängt' der Aufruf, bis der erste Thread (oder wer auch immer) das 'Leave' der CS Aufruf.

Genau hier würde ich es eben für sinnvoll halten, wenn der Zugriff erst gesperrt würde, wenn ein schreibender Zugriff ins Spiel kommt.
Wollen 10 oder 100 Threads gleichzeitig NUR LESEN wäre das ja eigentlich völlig unkritisch.

U.U. könnte das eine Anwendung deutlich beschleunigen.

Mikkey 3. Jul 2014 12:46

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Ich glaube nicht, dass die Spekulation über atomare Instruktionen in Bezug auf die gestellte Frage Sinn macht.

In DP geht es im Wesentlichen um Delphi, also um eine Hochsprache, die Umgebung sollte man generell als Black Box betrachten.

Somit kann man definieren:

Zitat:

Ein System (Programm) ist thread-sicher, wenn sein Zustand und damit die Zustände aller Subsysteme bei parallelen Aufrufen auf definierte Weise ändert.
Dies kann nur dann erreicht werden,

wenn das Programm nur Komponenten verwendet, die ihrerseits thread-sicher sind.
wenn der Zugriff und die Veränderung gemeinsam verwendeter Zustände aus geregelte Weise erfolgt.


P.S.
Übrigens gibt es eine Komponente System.SysUtils.TMultiReadExclusiveWriteSynchroniz er

Olli73 3. Jul 2014 12:55

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von stahli (Beitrag 1264258)
Dann wäre doch sinnvoll, z.B. 8 lesende Zugriffe mit
"CriticalSection.EnterRead" gleichzeitig zuzulassen und nur wenn dann ein "CriticalSection.EnterWrite" dazwischen kommen sollte die 8 Leseaktionen zu beenden, den Zugriff wirklich zu sperren und erst danach wieder andere Zugriffe zuzulassen.

Ist meine Überlegung sinnvoll? Oder gar schon so realisiert (in der Hilfe habe ich dazu nichts Genaues gefunden).

Multi-read-Exclusive-write-Synchronizer

stahli 3. Jul 2014 12:58

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
@Mikkey&Olli73

Danke, genau das meinte ich. :thumb:

stoxx 3. Jul 2014 18:19

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Sir Rufo (Beitrag 1264190)
Bei den aktuellen XEON-MultiCore-Boards hat übrigens jede CPU ihren eigenen Speicher.
[*]The memory slots associated with a given processor are unavailable if the corresponding processor socket is not populated.[*]A processor may be installed without populating the associated memory slots provided a second processor is installed with associated memory. In this case, the memory is shared by the processors. However, the platform suffers performance degradation and latency due to the remote memory.

Das ist aber nicht so richtig das was wir wollen. Scheinbar ist diese Architektur den immer weiter verbreiteten virtuellen (Cloud) Lösungen vorbehalten.
Es ging ja darum, gemeinsamenm Speicher gleichzeitig bearbeiten zu können.
Dass jeder Thread seinen eigenen Speicher bekommt, wäre mit jeder Architektur mit unterschiedlichen Variablen nicht sonderlich schwer zu lösen...

Sir Rufo 3. Jul 2014 19:00

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von stoxx (Beitrag 1264327)
Zitat:

Zitat von Sir Rufo (Beitrag 1264190)
Bei den aktuellen XEON-MultiCore-Boards hat übrigens jede CPU ihren eigenen Speicher.
[*]The memory slots associated with a given processor are unavailable if the corresponding processor socket is not populated.[*]A processor may be installed without populating the associated memory slots provided a second processor is installed with associated memory. In this case, the memory is shared by the processors. However, the platform suffers performance degradation and latency due to the remote memory.

Das ist aber nicht so richtig das was wir wollen. Scheinbar ist diese Architektur den immer weiter verbreiteten virtuellen (Cloud) Lösungen vorbehalten.
Es ging ja darum, gemeinsamenm Speicher gleichzeitig bearbeiten zu können.
Dass jeder Thread seinen eigenen Speicher bekommt, wäre mit jeder Architektur mit unterschiedlichen Variablen nicht sonderlich schwer zu lösen...

Die Situation bleibt aber doch gleich, oder weißt du auf welchem Core und welchem Riegel der Wert nun zu finden ist? Und wenn ich der Speicherstelle x einen Wert übergebe, dann muss jeder Thread von dieser Speicherstelle genau den geschriebenen Wert auslesen können.

Das war ja auch nur wegen MultiCore und alle teilen sich einen Arbeitsspeicher :)

stoxx 3. Jul 2014 23:09

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Mavarik (Beitrag 1264017)

Nutzt mir hier ein ThreadPool?

Benötige ich meinen Thread immer wieder, füttere ich „Ihn“ also nur mit neuen Daten und setze einen Event? Oder erzeuge ich den Thread jedes mal neu?

ich bin von den klassischen Anwendungen wie ThreadPools oder Ableitungen von der Klasse TThread ganz weg.
Bei mir gibt es eine Klasse "TThreadExecuter" .. die bekommt einfach einen MethodenPointer und ruft zyklisch wie ein Timer einen MethodenPointer der gewünschten Klasseauf. Meist 1 ms mit Sleep(1) .. aber oft ist das gar nicht notwendig.

So wird eine Funktion, die sich meistens ähnlich schimpft wie "CyclicMainJobs/ CyclicThreadProc" in einem anderen Thread aufgerufen.
Bei Bedarf kann der Aufruf auch schnell alternativ von einem "TTimerExecuter" durchgeführt werden, so wird anstatt eines zweiten Threads die Methode einfach von Hauptthread aus mit einem Timer aufgerufen.

Das Ganze hat den Vorteil, dass man auf alle Variablen der Klasse ohne Umstände Zugriffe hat.
Und das Ganze auch mehr zur "asynchronen" Eventverarbeitung tendiert und mit modernen OOP Konzepten gemeinsam harmoniert, als so eine popelige Schleife lediglich in der abgeleiteten Execute Procedure-

Mit einer übergebenen Instanz einer "SyncKlasse" können auch "teil-global" mehrere Objecte miteinander synchronisiert werden.

Das nur mal als "Brainstorming Idee"....

Aufpassen muss man natürlich, und genau drauf achten, welche Methoden von einem anderem als dem Hauptthread aufgerufen werden ..(werden können).. um dann sauber und ohne Fehler entsprechende Abschnitte im Code zu locken..

Dejan Vu 4. Jul 2014 06:56

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von stoxx (Beitrag 1264368)
Meist 1 ms mit Sleep(1) ..

An sich eine coole Idee, aber eine blöde Frage: Ist da nicht ein wenig zu viel context switching und overhead im spiel? Ok, 1000x pro Sekunde irgendwas aufrufen, um zu schauen, ob es etwas zu tun gibt, macht den Kohl nun auch nicht fett, aber ich dachte man ist vom Polling weggekommen. Oder habe ich das falsch verstanden?

Und welche Klasse meinst Du mit 'der gewünschten Klasse'? Und ist der 'Methodenpointer' in der 'gewünschten Klasse' nicht ein Verstoß gegen SRP? Schließlich macht die Methode etwas, das eher mit dem Thread bzw. einer Aktion im Thread zu zun hat, als mit der Klasse an sich.

Wie verhält es sich mit dem OCP, wenn Du eine weitere Aktion im Thread ausführen willst? Dann musst Du ja die gewünschte Klasse aufbohren, d.h. erweitern, obwohl Du an der Funktion der Klasse an sich nichts änderst?

Ich finde einen Workerthread(pool) mit Jobs, die man definiert, implementiert und den Arbeitern zur Verarbeitung gibt, immer noch am elegantesten. Man hat einen Pool pro Anwendung und schmeisst da die Jobs rein, fertig... ne, wie sagt der Fachmann :mrgreen: und schon ist der Drops gelutscht.

Mavarik 4. Jul 2014 09:22

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von stoxx (Beitrag 1264368)

Bei mir gibt es eine Klasse "TThreadExecuter" .. die bekommt einfach einen MethodenPointer und ruft zyklisch wie ein Timer einen MethodenPointer der gewünschten Klasseauf. Meist 1 ms mit Sleep(1) .. aber oft ist das gar nicht notwendig.

Autsch...

Ich würde die Klasse nicht ThreadExecuter, sondern lieber "TSaugdenAkkuleer" oder "TCPUCycleKiller" nennen...

Dafür gibt es doch Waitfor oder Multisyncwait damit der Thread schläft so lange er nicht gebraucht wird.

Mavarik

PS.: Ich habe mir hierfür eine mini Unit gemacht die so was erledigt.

Delphi-Quellcode:
unit UseMyThread;

interface

Uses System.Classes,System.SysUtils,System.SyncObjs,System.Generics.Collections;

type
  TMyThread = class(TThread)
   Private
      FRunning     : boolean;
      E_Event      : TEvent;
   Protected
      Procedure Execute;override;
   Public
      Constructor Create;
      Destructor Destroy;override;
      procedure Terminate; reintroduce; virtual;
      Procedure MyExecute;Virtual;Abstract;
      Procedure MyFree;Virtual;Abstract;
      Procedure Go;
  end;

  // ProcessorCount


implementation

{ TMyThread }

constructor TMyThread.Create;
begin
  inherited Create(true);

  E_Event := TEvent.Create(NIL,false,false,'');
  FRunning := false;

  FreeOnTerminate := false;
end;

destructor TMyThread.Destroy;
begin
  Terminate;

  inherited;

  try
    MyFree;
  except
  end;

  try
    E_Event.Free;
  except
  end;
end;

procedure TMyThread.Execute;
begin
  while not(Terminated) do
    begin
      try
        FRunning := false; // Atom ?

        E_Event.WaitFor(INFINITE);

        if Terminated then
          exit;

        FRunning := true;
        MyExecute;
      except
      end;
    end;
end;

procedure TMyThread.Go;
begin
  if not(Started) then
    Start;

  E_Event.SetEvent;
end;

procedure TMyThread.Terminate;
begin
  inherited Terminate;
  E_Event.SetEvent;
end;


end.

Dejan Vu 4. Jul 2014 09:56

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Mavarik (Beitrag 1264399)
Ich würde die Klasse nicht ThreadExecuter, sondern lieber "TSaugdenAkkuleer" oder "TCPUCycleKiller" nennen...

Nicht jeder Entwickelt für akkubetriebene Küchenschneidbretter.

Eine Frage zu deinem Code: Hast Du schon mal was von Fail Fast gehört, oder einfach ausgedrückt: "Ordentliches Exception Handling"? Dein "An die Wand gefahren? Merkt doch keiner" ist eventuell schwierig beim Finden von Fehlern.

Noch eine Frage: Wo ist der Mehrwert der Methode 'Go' ggü 'Resume'? Klar, der Aufruf von 'Suspend' ist ein No-Go, aber ansonsten?

Sir Rufo 4. Jul 2014 09:57

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
@Frank

Den Thread im Suspended-Mode zu starten macht irgendwie keinen Sinn, da der doch schon durch den Event wartet.

Ich würde auch nicht
Delphi-Quellcode:
TThread.Terminate
überschreiben, sondern
Delphi-Quellcode:
Tthread.TerminatedSet
, denn das ist schon als
Delphi-Quellcode:
virtual
deklariert und somit zum Überschreiben gedacht.

Die Klasse selber würde ich noch als
Delphi-Quellcode:
abstract
deklarieren (nur wegen der Dokumentation), denn ohne Ableitung ist die ja so nicht lauffähig.

Einfach so die Exception wegfangen ist auch nicht gerade schön, und wenn fangen, dann nur so:
Delphi-Quellcode:
try
  MyExecute;
except
  // Nur spezielle Exceptions fangen, die MyExecute bewusst ausgelöst hat
  // Alle anderen unvorhergesehenen werden durchgereicht
  on E:MyExecuteException do
    begin
    end;
end;
Das hier
Delphi-Quellcode:
try
  E_Event.Free;
except
end;
ist auch unsauber. Wenn meine Klasse nicht funktioniert, dann möchte ich die Fehler um die Ohren geschlagen bekommen.

Bei dem
Delphi-Quellcode:
MyExecute
und
Delphi-Quellcode:
MyFree
sieht das etwas anders aus, da hierfür nicht die Klasse
Delphi-Quellcode:
TMyThread
zuständig ist.

Aber was passiert denn, wenn in
Delphi-Quellcode:
MyExecute
ein übler Fehler passiert (StackOverflow)?
Der Code kann immer wieder ausgeführt werden, ohne jeden Hinweis auf den Fehler.

Das
Delphi-Quellcode:
Terminate
im Destructor ist überflüssig (wird schon implizit vom
Delphi-Quellcode:
inherited
aufgerufen ... ach nee, bei dir ja nicht ;))

Mavarik 4. Jul 2014 10:08

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Sir Rufo (Beitrag 1264406)
@Frank
Den Thread im Suspended-Mode zu starten macht irgendwie keinen Sinn, da der doch schon durch den Event wartet.

Sicher? Wird der Thread nicht bei
Delphi-Quellcode:
Inherited Create(false)
schon gestartet? Dann ist der Event noch nicht Created!

Zitat:

Zitat von Sir Rufo (Beitrag 1264406)
Ich würde auch nicht
Delphi-Quellcode:
TThread.Terminate
überschreiben, sondern
Delphi-Quellcode:
Thread.TerminatedSet
, denn das ist schon als
Delphi-Quellcode:
virtual
deklariert und somit zum Überschreiben gedacht.

Wenn Du eine Delphi Version hast die diese Implementierung schon hat, gebe ich dir Recht. D2007 hat das noch nicht.

Zitat:

Zitat von Sir Rufo (Beitrag 1264406)
@
Die Klasse selber würde ich noch als
Delphi-Quellcode:
abstract
deklarieren (nur wegen der Dokumentation), denn ohne Ableitung ist die ja so nicht lauffähig.

OK.. Kann man machen... Obwohl der Compiler das auch so meldet.. Aber Du hast recht... Bin neu im "Abstract" Bereicht :stupid:

Zitat:

Zitat von Sir Rufo (Beitrag 1264406)
@
Einfach so die Exception wegfangen ist auch nicht gerade schön

Das ist Teil unseres "Unser Programm hat keine Exceptions" Konzept... Bitte hierzu keine Diskussion anfangen, Danke...

Mavarik

Mavarik 4. Jul 2014 10:09

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Dejan Vu (Beitrag 1264405)
Zitat:

Zitat von Mavarik (Beitrag 1264399)
Ich würde die Klasse nicht ThreadExecuter, sondern lieber "TSaugdenAkkuleer" oder "TCPUCycleKiller" nennen...

Nicht jeder Entwickelt für akkubetriebene Küchenschneidbretter.

Und auch nicht für Notebooks?

Dejan Vu 4. Jul 2014 10:16

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Sir Rufo (Beitrag 1264406)
...und wenn fangen, dann nur so:
Delphi-Quellcode:
try
  MyExecute;
except
  // Nur spezielle Exceptions fangen, die MyExecute bewusst ausgelöst hat
  // Alle anderen unvorhergesehenen werden durchgereicht
  on E:MyExecuteException do
    begin
    end;
end;

Hmm... Kommentarlos? Noch nicht mal loggen? Gewagt, gewagt. Würde ich nie nicht niemals so machen. Wenn es eine Exception als Flusskontrolle gibt, dann muss das im 'MyExecute' abgefangen werden. Diese Methode hat sorge zu tragen, das sie sauber terminiert, bzw. kontrolliert Exceptions weiterleitet. Dann muss aber in der aufrufenden Methode eine vollständige Exceptionbehandlung erfolgen, meinst Du nicht?

Zitat:

Zitat von Mavarik (Beitrag 1264409)
Und auch nicht für Notebooks?

:thumb: Nö. :mrgreen: Nur für Industrieboliden. Aber mal im Ernst: Du hast Recht. Stromsparen tut nicht weh und ist auch nicht verkehrt.

DeddyH 4. Jul 2014 10:23

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Wahrscheinlich verbrauchen sauber behandelte Exceptions zuviel Strom :lol:

Mavarik 4. Jul 2014 10:51

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Dejan Vu (Beitrag 1264411)
Hmm... Kommentarlos? Noch nicht mal loggen? Gewagt, gewagt.

Das hab ich nicht gesagt... Ich wollte Euch nicht mir meinem "Restsource" verwirren... 8-)

Der schöne Günther 4. Jul 2014 10:52

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Dejan Vu (Beitrag 1264411)
Wenn es eine Exception als Flusskontrolle gibt, dann muss das im 'MyExecute' abgefangen werden. Diese Methode hat sorge zu tragen, das sie sauber terminiert, bzw. kontrolliert Exceptions weiterleitet. Dann muss aber in der aufrufenden Methode eine vollständige Exceptionbehandlung erfolgen

Das ist eine der wenigen Stellen wo ich Java (Direktive
Delphi-Quellcode:
throws
für Methoden) vermisse. In C# bubbelt auch alles immer weiter nach oben (wie in Delphi), oder?


Aber irgendwie kommen wir vom ursprünglichen Thema ab...

Dejan Vu 4. Jul 2014 10:56

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Mavarik (Beitrag 1264422)
Das hab ich nicht gesagt... Ich wollte Euch nicht mir meinem "Restsource" verwirren... 8-)

Ich meinte ja auch nicht dich mit dieser Anmerkung.
Zitat:

Zitat von Der schöne Günther (Beitrag 1264424)
Das ist eine der wenigen Stellen wo ich Java (Direktive
Delphi-Quellcode:
throws
für Methoden) vermisse. In C# bubbelt auch alles immer weiter nach oben (wie in Delphi), oder?

OT: Ja, wir kommen vom Thema ab, ja, bei C# bubbelt es auch weiter nach oben wie in Delphi und Java und nein, ich vermisse die 'throws' Direktive nicht, denn es ist kein Mehrwert an Übersichtlichkeit und Stabilität (vor allen Dingen nicht: Produktivität).

Meiner Meinung nach kann man über Exceptions mal wieder einen Fred aufmachen. Aber hier ist, dank Günther, dem Schönen, auch von meiner Seite aus Schluss.

Sir Rufo 4. Jul 2014 13:05

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Mavarik (Beitrag 1264408)
Zitat:

Zitat von Sir Rufo (Beitrag 1264406)
@Frank
Den Thread im Suspended-Mode zu starten macht irgendwie keinen Sinn, da der doch schon durch den Event wartet.

Sicher? Wird der Thread nicht bei
Delphi-Quellcode:
Inherited Create(false)
schon gestartet? Dann ist der Event noch nicht Created!

Nein, definitiv nicht!

PS
Wenn du so eine Angst davor hast, dann leg die Erzeugung des Events einfach vor das
Delphi-Quellcode:
inherited Create( False );
. :)
Delphi-Quellcode:
constructor TMyThread.Create;
begin
  E_Event := TEvent.Create(NIL,false,false,'');
  FRunning := false;

  inherited Create( False ); // nein, nicht schlafen :)

  FreeOnTerminate := false;
end;
Der Thread wird erst nach dem kompletten Abarbeiten des Destructors Constructors (Danke an Uwe) gestartet (das ist absolut gesichert!). Und das auch nicht direkt sofort, sondern auch erst nach einer gewissen Dauer, weil der Thread erstmal warten muss, bis er an der Reihe ist.

Führe einfach mal dieses hier aus und wundere Dich ;)
Delphi-Quellcode:
type
  TMyThread = class( TThread )
  protected
    procedure Execute; override;
  end;

procedure TMyThread.Execute;
begin
  inherited;
end;

procedure ThreadTest;
var
  LThread : TThread;
  LCount : Int64;
begin
  LCount := 0;
  LThread := TMyThread.Create( False );
  try
    while not LThread.Started do
      Inc( LCount );
  finally
    LThread.Free;
  end;
  Writeln( 'Gestartet nach ', LCount, ' Loops' );
end;

Uwe Raabe 4. Jul 2014 13:07

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
Zitat:

Zitat von Sir Rufo (Beitrag 1264450)
Der Thread wird erst nach dem kompletten Abarbeiten des Destructors gestartet (das ist absolut gesichert!).

Constructors!

stoxx 4. Jul 2014 16:18

AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
 
[QUOTE=Mavarik;1264399]
Zitat:

Zitat von stoxx (Beitrag 1264368)


Autsch...

Ich würde die Klasse nicht ThreadExecuter, sondern lieber "TSaugdenAkkuleer" oder "TCPUCycleKiller" nennen...

Dafür gibt es doch Waitfor oder Multisyncwait damit der Thread schläft so lange er nicht gebraucht wird.

Dein Ton ist ja gerade noch so freundlich, aber schon recht grenzwertig.
Woher nimmst Du die Behauptung, dass die Klasse intern das sleep nicht mit Waitfor realisiert?
Du kannst ihn doch programmieren, wie Du Lust hast, und den FunctionCall auch erst nach einem einkommenden Event generieren.

Wenn ich aber ständig eine Response brauche, weil ständig Dinge getan/geprüft werden müssen, , dann muss er wohl in der Tat auch ständig bereit sein, um gewisse Dinge zu erledigen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:30 Uhr.
Seite 1 von 2  1 2      

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