Delphi-Version: 2007
Lokale Variable Threadsicher?
Moin zusammen,
bei uns ist eine heiße Diskussion über Threadsicherheit entbrannt... hoffentlich gibt es hier eine klare Antwort. Folgendes: 1..n Threads benutzen ein einmal erzeugtes Objekt. Die Threads rufen eine Funktion namens Cmd parallel auf.
Code:
Jetzt gibt es zwei Theorien.
function TMyObject.Cmd(tx: String; var rx: String): Boolean;
var myClient: TMyClient; begin //myClient erzeugen //myClient benutzen //FreeAndNil... end; 1. Die 'myClient' wird bei parallelen Aufrufen an den gleichen Pointer erzeugt. Und damit ist diese Konstrukt NICHT thread-sicher! 2. 'myClient' wird an verschiedenen Pointern erzeugt und solange man keine globale Variablen benuzt, ist es thread-sicher. 2a. Wenn den so ist warum funktioniert dann Rekursion. Danke+Gruß Matthias |
AW: Lokale Variable Threadsicher?
Die lokalen Variablen und die Parameter einer Methode werden auf dem Stack angelegt oder es wird ein Register der CPU benutzt. Das ist in jedem Fall threadsicher. Bei Pointern, dynamischen Arrays und Klasseninstanzen (sind ja auch Pointer) muss man aber wiederum aufpassen. Die Inhalte liegen nämlich nicht auf dem Stack.
In dem konkreten Beispiel wird aber die Klasseninstanz innerhalb der Methode erzeugt und freigegeben. Das ist wiederum sicher. Rekursion hat damit erstmal gar nichts zu tun. Auch hier muss man eine konkrete Implementation sehen, um Threadsicherheit beurteilen zu können. Es gelten da die gleichen Bedingungen. |
AW: Lokale Variable Threadsicher?
Zitat:
Zitat:
Beispiel:
Delphi-Quellcode:
Wenn du dort z.B. 3 übergibst, wird innerhalb deines Aufrufs Test(3) noch einmal Test(2) und Test(1) aufgerufen. Ob du darin dann jeweils noch einmal lokale Variablen benutzt oder nicht, ist egal. Denn die gelten jeweils nur innerhalb des aktuellen Aufrufs. Das sich in der Rekursion ändernde Element ist a, also der Parameter. Und der wird auch nur dem jeweiligen Aufruf mitgegeben.
function Test(const a: Integer): Integer;
begin if a > 1 then Result := Test(a - 1) else Result := 1; end; Wir könnten hier sicherlich auch erklären wie das intern genauer funktioniert, aber ich glaube das führt zu weit und verwirrt eher. (Auch wenn es sehr interessant sein kann. ;-)) |
AW: Lokale Variable Threadsicher?
Falls Ihr euch regelmäßig zum Philosophieren über den Begriff Threadsicherheit trefft - Ich fand den kleinen Artikel ganz nett: Eric Lippert - What is this thing you call thread-safe?
|
AW: Lokale Variable Threadsicher?
Zitat:
Delphi-Quellcode:
Wenn das so wäre, dann würde man sich ja bei jedem Aufruf die vorherige damit erzeugte Instanz vernageln.
function MyFactory : TObject;
var LObj : TObject; begin LObj := TObject.Create; Result := LObj; end; Kann also definitv nicht zutreffen. |
AW: Lokale Variable Threadsicher?
Zwar ist immer noch nicht klar warum es an dieser Stelle 'knallt' aber, dass muss dann wohl einen anderen Grund haben als das Multi-Threading.
Vielen Dank für die Antworten! Grüße Matthias |
AW: Lokale Variable Threadsicher?
Zitat:
Update: Bzw. es kann schon daran liegen, allerdings ist die Ursache eine falsche Handhabung. Eine lokale Variable ist beim Aufruf nicht initialisiert. Soll heißen, die zeigt auf irgendeine Stelle im Speicher. Greift man nun auf diese Variable einfach so zu, dann können die lustigsten Sachen passieren. z.B. das hier
Delphi-Quellcode:
kann zu einer Exception oder auch dazu führen, dass eine x- beliebige Form geschlossen wird ;)
procedure TForm1.Foo;
var LForm : TForm; begin LForm.Close; end; Darum schmeisst der Compiler auch eine Warnung aus, wenn eine lokale Variable nicht initialisiert wurde. Das solltest du zuerst prüfen (Compiler-Warnungen, Initialisierung der lokalen Variablen) Danach, ob irgendwelche Abhängigkeiten von aussen (z.B. bei einer lokal erzeugten Query eine "globale" Connection benutzen) eingeschleust werden. |
AW: Lokale Variable Threadsicher?
Was tritt denn auf?
Vom Namen hier sieht das aus wie eine Methode zum Absetzen einer Zeichenfolge an ein Gerät und man bekommt darauf eine Antwort. Wenn wir hier jetzt bsp. eine Leitung haben, auf der man tunlichst die erste Nachricht zuende schreibt und die Antwort empängt bevor man mit der zweiten weitermacht, wären kritische Abschnitte (zumindest für den Hardware-Teil auf der physikalischen Leitung) genau das richtige... |
AW: Lokale Variable Threadsicher?
Zitat:
|
AW: Lokale Variable Threadsicher?
@Sir Rufo
Ich habe mir abgewöhnt Compilerwarungen zu ignorieren, das rächt sich irgendwann...:) Es geht darum, dass ein weiterer Service via TCP angesprochen wird. Am Empfängerservice ist zu sehen, dass die Anfragen nahezu zur gleichen Zeit (<=1ms) ankommen und den gleichen Port benutzen. Deswegen war ich auf die lokalen Variablen gestoßen. Das Ganze konnte ich zum Testen mit einer TCriticalSection lösen, also muss das Problem ja innerhalb dieser Funtkion liegen. Sind Firmensourcen daher kann ich den Code leider nicht einstellen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:38 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