AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Lokale Variable Threadsicher?

Ein Thema von saihttam · begonnen am 30. Mai 2013 · letzter Beitrag vom 31. Mai 2013
Antwort Antwort
Seite 1 von 2  1 2      
saihttam

Registriert seit: 30. Mai 2013
5 Beiträge
 
#1

Lokale Variable Threadsicher?

  Alt 30. Mai 2013, 09:56
Delphi-Version: 2007
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:
function TMyObject.Cmd(tx: String; var rx: String): Boolean;
var
  myClient: TMyClient;
begin
  //myClient erzeugen
  //myClient benutzen
  //FreeAndNil...
end;
Jetzt gibt es zwei Theorien.

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
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#2

AW: Lokale Variable Threadsicher?

  Alt 30. Mai 2013, 10:07
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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Lokale Variable Threadsicher?

  Alt 30. Mai 2013, 10:59
2. 'myClient' wird an verschiedenen Pointern erzeugt und solange man keine globale Variablen benuzt, ist es thread-sicher.
Wobei du zu den globalen Variablen auch die Felder des Objekts zählen musst, zu dem deine Funktion Cmd gehört, also was dort unter private, public usw. steht.

2a. Wenn den so ist warum funktioniert dann Rekursion.
Weil du dort die Parameter für den einzelnen Aufruf als Parameter übergibst. Du benutzt dort ja nicht die selbe lokale Variable über mehrere Rekursionsschritte hinweg.

Beispiel:
Delphi-Quellcode:
function Test(const a: Integer): Integer;
begin
  if a > 1 then
    Result := Test(a - 1)
  else
    Result := 1;
end;
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.

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. )
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Lokale Variable Threadsicher?

  Alt 30. Mai 2013, 12:07
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?
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Lokale Variable Threadsicher?

  Alt 30. Mai 2013, 12:55
1. Die 'myClient' wird bei parallelen Aufrufen an den gleichen Pointer erzeugt. Und damit ist diese Konstrukt NICHT thread-sicher!
Das ist generell schon mal absolut falsch - und wäre auch absolut tödlich

Delphi-Quellcode:
function MyFactory : TObject;
var
  LObj : TObject;
begin
  LObj := TObject.Create;
  Result := LObj;
end;
Wenn das so wäre, dann würde man sich ja bei jedem Aufruf die vorherige damit erzeugte Instanz vernageln.
Kann also definitv nicht zutreffen.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
saihttam

Registriert seit: 30. Mai 2013
5 Beiträge
 
#6

AW: Lokale Variable Threadsicher?

  Alt 31. Mai 2013, 10:32
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
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Lokale Variable Threadsicher?

  Alt 31. Mai 2013, 10:50
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
Es liegt nicht an den lokalen Variablen

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:
procedure TForm1.Foo;
var
  LForm : TForm;
begin
  LForm.Close;
end;
kann zu einer Exception oder auch dazu führen, dass eine x- beliebige Form geschlossen wird
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.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (31. Mai 2013 um 11:02 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Lokale Variable Threadsicher?

  Alt 31. Mai 2013, 11:02
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...
  Mit Zitat antworten Zitat
sahimba

Registriert seit: 14. Nov 2011
Ort: Berlin, Hauptstadt der DDR
137 Beiträge
 
Delphi 10 Seattle Professional
 
#9

AW: Lokale Variable Threadsicher?

  Alt 31. Mai 2013, 12:01
In dem konkreten Beispiel wird aber die Klasseninstanz innerhalb der Methode erzeugt und freigegeben. Das ist wiederum sicher.
Das lässt sich so nicht sagen, da wir nicht wissen, was die Instanz der erzeugten Klasse intern "tut". Möglicherweise greift diese auf globale Strukturen zu ohne sich um eine Synchronisierung zu kümmern.
  Mit Zitat antworten Zitat
saihttam

Registriert seit: 30. Mai 2013
5 Beiträge
 
#10

AW: Lokale Variable Threadsicher?

  Alt 31. Mai 2013, 12:42
@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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:58 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