![]() |
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 ![]() 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 ![]() Wann brauche ich ein ![]() Wann brauche ich eine ![]() Oder reicht mir ein ![]() Sicherlich gibt es hierzu Tutorials. Zum Beispiel ![]() Besonders bemerkenswert ist hieraus folgenden Satz: Zitat:
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:
Brauche ich für den Zugriff auf Edit10.Text ein Syncronize?
procedure TMyThread.Execute;
var S : String; begin while not(Terminated) do begin S := Edit10.Text; Foo(S); End; end; 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:
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 ![]() 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 ![]() 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: |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Save?“
|
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 |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Save?“
Zitat:
Aber wenigstens konsequent durchgesetzt... Zitat:
|
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:
|
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Save?“
Zitat:
Gruß K-H |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
Zitat:
Zitat:
|
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
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:
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:
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:
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... |
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).
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 :) |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
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:
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 ![]() 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 .... |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
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. |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
Bei den aktuellen XEON-MultiCore-Boards hat übrigens jede CPU ihren eigenen Speicher. Zitat:
|
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
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:
Ich meine ja nicht den Cache sondern den echten physischen RAM. (Als Riegel ;-) ) ![]() |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
![]() 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:
|
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
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:
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. |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
![]() Anhang 41397 intel 3.2.2.2 Memory Slot Identification and Population Rules (S.25)
|
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). |
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.
|
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Ich habe das Thema nur oberflächlich überflogen. Was ich kurz anmerken wollte:
Zitat:
Delphi-Quellcode:
steckt- Dann ist der doch nicht unbedingt so ausgerichtet dass die CPU den in einem Rutsch ins Register schaufelt und zwei Takte braucht.
packet record
Irgendwie sowas, oder? |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
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. |
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:
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 |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
![]() |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
@Mikkey&Olli73
Danke, genau das meinte ich. :thumb: |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
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... |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
Das war ja auch nur wegen MultiCore und alle teilen sich einen Arbeitsspeicher :) |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
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.. |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
Und welche Klasse meinst Du mit 'der gewünschten Klasse'? Und ist der 'Methodenpointer' in der 'gewünschten Klasse' nicht ein Verstoß gegen ![]() Wie verhält es sich mit dem ![]() 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. |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
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. |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
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? |
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:
überschreiben, sondern
TThread.Terminate
Delphi-Quellcode:
, denn das ist schon als
Tthread.TerminatedSet
Delphi-Quellcode:
deklariert und somit zum Überschreiben gedacht.
virtual
Die Klasse selber würde ich noch als
Delphi-Quellcode:
deklarieren (nur wegen der Dokumentation), denn ohne Ableitung ist die ja so nicht lauffähig.
abstract
Einfach so die Exception wegfangen ist auch nicht gerade schön, und wenn fangen, dann nur so:
Delphi-Quellcode:
Das hier
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;
Delphi-Quellcode:
ist auch unsauber. Wenn meine Klasse nicht funktioniert, dann möchte ich die Fehler um die Ohren geschlagen bekommen.
try
E_Event.Free; except end; Bei dem
Delphi-Quellcode:
und
MyExecute
Delphi-Quellcode:
sieht das etwas anders aus, da hierfür nicht die Klasse
MyFree
Delphi-Quellcode:
zuständig ist.
TMyThread
Aber was passiert denn, wenn in
Delphi-Quellcode:
ein übler Fehler passiert (StackOverflow)?
MyExecute
Der Code kann immer wieder ausgeführt werden, ohne jeden Hinweis auf den Fehler. Das
Delphi-Quellcode:
im Destructor ist überflüssig (wird schon implizit vom
Terminate
Delphi-Quellcode:
aufgerufen ... ach nee, bei dir ja nicht ;))
inherited
|
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
Delphi-Quellcode:
schon gestartet? Dann ist der Event noch nicht Created!
Inherited Create(false)
Zitat:
Zitat:
Zitat:
Mavarik |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
|
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
Zitat:
|
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Wahrscheinlich verbrauchen sauber behandelte Exceptions zuviel Strom :lol:
|
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
|
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
Delphi-Quellcode:
für Methoden) vermisse. In C# bubbelt auch alles immer weiter nach oben (wie in Delphi), oder?
throws
Aber irgendwie kommen wir vom ursprünglichen Thema ab... |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
Zitat:
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. |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
PS Wenn du so eine Angst davor hast, dann leg die Erzeugung des Events einfach vor das
Delphi-Quellcode:
. :)
inherited Create( False );
Delphi-Quellcode:
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.
constructor TMyThread.Create;
begin E_Event := TEvent.Create(NIL,false,false,''); FRunning := false; inherited Create( False ); // nein, nicht schlafen :) FreeOnTerminate := false; end; 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; |
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
Zitat:
|
AW: Die Frage aller Fragen (Sammlung): „Ist das Thread-Safe?“
[QUOTE=Mavarik;1264399]
Zitat:
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 09:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz