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, 08: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.629 Beiträge
 
Delphi 12 Athens
 
#2

AW: Lokale Variable Threadsicher?

  Alt 30. Mai 2013, 09: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
sahimba

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

AW: Lokale Variable Threadsicher?

  Alt 31. Mai 2013, 11: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
 
#4

AW: Lokale Variable Threadsicher?

  Alt 31. Mai 2013, 11: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
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.912 Beiträge
 
Delphi 12 Athens
 
#5

AW: Lokale Variable Threadsicher?

  Alt 31. Mai 2013, 15:21
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.
Und wie wird diese Kommunikation gemacht? Wirklich rein mit lokalen Variablen?

Oder steckt da vielleicht eine TCP-Verbindungskomponente global unter private oder so... (denn ich vermute ja nicht, dass die Verbindung ständig neu aufgebaut wird)

Eine Möglichkeit dies ohne Synchronisation zu lösen:
Statt var einfach threadvar, dann ist die globale Variable threadspezifisch.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
saihttam

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

AW: Lokale Variable Threadsicher?

  Alt 31. Mai 2013, 15:40
In diesem Fall wird die Verbindung aufgebaut und direkt wieder geschlossen.

Ich benutze die Indy's TIdTCPClient Klasse. Mein Source ist sehr übersichtlich. Ich glaube deswegen (momentan) nicht, dass es an meinem Source liegt. Variablen benutze ich dort eigentlich nur lesend (Zielname, -port, timeout-Konstanten), der Rest sind die Parameter (rx, tx) der Funktion.

Stimmt 'threadvar' hatte ich schon verdrängt. Werde ich mal versuchen...

Ich mache nu' Feierabend,
euch ein schönes WE!
Gruß Matthias
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Lokale Variable Threadsicher?

  Alt 31. Mai 2013, 12:22
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.
Das hatte ich ja mit den Ausführungen in dem Abschnitt davor gemeint.

In dem Fall liegt das Problem aber nicht in der Methode selbst oder an der dort erzeugten Klasseninstanz (d.h. jeder Methodenaufruf verwendet seine eigene Klasseninstanz - auch bei Multithreading), sondern an der Implementation der Klasse. Darüber können wir aber allenfalls spekulieren.
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.912 Beiträge
 
Delphi 12 Athens
 
#8

AW: Lokale Variable Threadsicher?

  Alt 30. Mai 2013, 09: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.196 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: Lokale Variable Threadsicher?

  Alt 30. Mai 2013, 11: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
 
#10

AW: Lokale Variable Threadsicher?

  Alt 30. Mai 2013, 11: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
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 21:22 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-2025 by Thomas Breitkreuz