AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Änderungen von Variablen synchronisieren

Ein Thema von Breager · begonnen am 17. Mär 2012 · letzter Beitrag vom 20. Mär 2012
Antwort Antwort
Seite 2 von 4     12 34   
Furtbichler
(Gast)

n/a Beiträge
 
#11

AW: Änderungen von Variablen synchronisieren

  Alt 18. Mär 2012, 08:48
Aber ... innerhalb des Threads könnte man ja direkt auf FIntStr zugreifen, aber dieser Zugriff ist nicht abgesicht (über die CS), also sollte der Zugriff auch innerhalb des Threads über die Eigenschaft und nicht über das Feld erfolgen.
Oder man baut eine eigene Klasse dafür: TThreadsafeString, der gar nichts anderes erlaubt, als den Zugriff über die Property und damit über die CS.
  Mit Zitat antworten Zitat
Breager

Registriert seit: 18. Feb 2012
40 Beiträge
 
#12

AW: Änderungen von Variablen synchronisieren

  Alt 18. Mär 2012, 11:13
So, vielen Dank nochmal an alle. Ich habe nun alle wichtigen Operationen der TList (Add, Insert, Delete, Exchange, Clear) und natürlich das Umbenennen des Strings mit Hilfe von TCriticalSection in kritische Abschnitte gepackt. Die Performance ist nach wie vor gut.

Zitat von himitsu:
Microsoft hat leider die Verwaltung der CS umgestllt.
In den Debuginfos der CS gibt es eigentlich ein Event-Objekt, an welches ich mich dranhängen wollte, um nicht pollen zu müssen, aber leider ist dort, zumindestens in Win7/Server2008/Server2011 immer nur "Nichts" (0) eingetragen.
Das kann ich im Moment leider nicht testen. Bin mir immer noch nicht sicher, ob ich nun pollen sollte oder nicht? Ist das vom System oder vom Compiler abhängig?
Delphi-Quellcode:
While not(FCS.TryEnter) do InfiniteLoop;
... tue irgendetwas
FSC.Leave
  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
 
#13

AW: Änderungen von Variablen synchronisieren

  Alt 18. Mär 2012, 11:23
Die Mühe bei der TList hättest du dir sparen können, wenn du einfach Delphi-Referenz durchsuchenTThreadList benutzen würdest

BTW: Du solltest immer mit einem Schutzblock arbeiten:
Delphi-Quellcode:
While not(FCS.TryEnter) do InfiniteLoop;
try
  ... tue irgendetwas
finally
  FSC.Leave;
end;
und auch das ist eigentlich völlig überflüssig, weil du hiermit genau das gleiche erreichst wie mit
Delphi-Quellcode:
FCS.Enter; // Wartet so lange, bis die CS betreten werden kann
try
  ... tue irgendetwas
finally
  FCS.Leave;
end;
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
Breager

Registriert seit: 18. Feb 2012
40 Beiträge
 
#14

AW: Änderungen von Variablen synchronisieren

  Alt 18. Mär 2012, 11:40
TThreadlist hatte ich auch bereits gefunden. Allerdings fehlt dort Insert und Exchange oder habe ich etwas übersehen? Gut, das könnte man im Notfall noch selbst implementieren.
Zitat von Sir Rufo:
BTW: Du solltest immer mit einem Schutzblock arbeiten.
Ja, hast recht. Werde ich in Zukunft sofort einbauen.

EDIT: Das geht ja anscheinend doch. Muss ich mir nochmal gründlich unter die Lupe nehmen. Man lernt eben nie aus. Vielen Dank für den Hinweis.

Geändert von Breager (18. Mär 2012 um 11:58 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.678 Beiträge
 
Delphi 11 Alexandria
 
#15

AW: Änderungen von Variablen synchronisieren

  Alt 18. Mär 2012, 12:31
Pollen ist hier leider die einzige Möglichkeit, wenn man ein TimeOut benötigt, also bei der CS.
Ansonsten müßte man auf Events (z.B. MSDN-Library durchsuchenSetEvent oder Delphi-Referenz durchsuchenTEvent) umsteigen.

Beim Pollen muß meventuell an aufpassen, daß man nicht die CPU hochtreibt.
Ich bei da Pausen in die Schleife, so mit je um die 20 Millisekunden.
Aber dort kann man sich unter umständen auch aussperren, wenn zwei/mehrere Threads in schneller Follge drauf zugreifen und zwischen 2 Zugriffen die Zeit kürzer ist, als die Pause.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu (18. Mär 2012 um 12:33 Uhr)
  Mit Zitat antworten Zitat
Breager

Registriert seit: 18. Feb 2012
40 Beiträge
 
#16

AW: Änderungen von Variablen synchronisieren

  Alt 19. Mär 2012, 17:48
Zitat von himitsu:
Beim Pollen muß meventuell an aufpassen, daß man nicht die CPU hochtreibt.
Ich bei da Pausen in die Schleife, so mit je um die 20 Millisekunden.
Aber dort kann man sich unter umständen auch aussperren, wenn zwei/mehrere Threads in schneller Follge drauf zugreifen und zwischen 2 Zugriffen die Zeit kürzer ist, als die Pause.
Da reicht sogar schon eine Millisekunde aus Hatte ich die letzten Tage mal selbst getestet. Hatte das ganz falsch verstanden. Dachte, das Enter wartet genauso wenig wie das TryEnter. Habs jetzt erstmal ohne Pollen umgesetzt.

Und zwar habe ich mir eine einfache threadsichere Klasse (mit CriticalSections) gebaut, die sich um alles kümmert. Ich weiss, dafür gibts die ThreadList, die fand ich von der Schreibarbeit jedoch auch nicht wesentlich angenehmer. In meiner Klasse überlasse ich es dem Benutzer, ob er die Liste manuell sperren möchte oder ob dies automatisch geschieht.
Delphi-Quellcode:
interface
Uses Classes, SysUtils, SyncObjs;
type

  TMyList = class
    private
      MyList:TList;
      FCS : TCriticalSection;
      MustLock:Boolean; //Liste muss gesperrt werden
      Procedure Lock; //Internes Sperren
      Procedure Unlock; //Internes Freigeben

    public
      Procedure Locklist; //Manuell sperren
      Procedure Unlocklist; //Manuell freigeben

      Constructor Create;
      Destructor Destroy;
      Function Count:Integer;
      ...
   end;

implementation

Constructor TMyList.Create;
Begin
  MyList:=TList.Create;
  FCS := TCriticalSection.Create;
  MustLock:=True; //Liste muss automatisch gesperrt werden
End;

Procedure TMyList.Lock;
Begin
IF MustLock then
   FCS.Enter;
End;

procedure TMyList.Unlock;
begin
IF MustLock then
   FCS.Release;
end;


Procedure TMyList.Locklist;
Begin
 FCS.Enter;
 MustLock:=False; //Liste muss später NICHT automatisch gesperrt werden
End;

Procedure TMyList.Unlocklist; //EDIT: Reihenfolge der Codezeilen wurde getauscht
Begin
  MustLock:=True; //Liste muss später automatisch gesperrt werden
  FCS.Release;
End;

Function TMyList.Count:Integer;
Begin
 lock;
 try
  Result:=MyList.Count;
 finally
  unlock;
 end;
End;
Der Vorteil hierbei ist, dass man bei Bedarf einen größeren Code-Block sperren kann, ansonsten muss ich mich um nichts kümmern.

Mal noch ne letzte Frage, wenn man in einer Schleife mehrere Items aus der Liste löscht, ist es dann besser, die komplette Schleife zu sprerren oder nur die einzelnen Delete?

Geändert von Breager (19. Mär 2012 um 18:16 Uhr)
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
2.885 Beiträge
 
Delphi 2009 Professional
 
#17

AW: Änderungen von Variablen synchronisieren

  Alt 19. Mär 2012, 17:58

Delphi-Quellcode:

Procedure TMyList.Unlocklist;
Begin
  FCS.Release;
  MustLock:=True; //Liste muss später automatisch gesperrt werden
End;
Die beiden Zeilen würde ich sicherheitshalber tauschen:

Delphi-Quellcode:

Procedure TMyList.Unlocklist;
Begin
  MustLock:=True; //Liste muss später automatisch gesperrt werden
  FCS.Release; // erst jetzt darf ein anderer Thread an die Liste
End;
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Breager

Registriert seit: 18. Feb 2012
40 Beiträge
 
#18

AW: Änderungen von Variablen synchronisieren

  Alt 19. Mär 2012, 18:06
Zitat von mjustin:
Die beiden Zeilen würde ich sicherheitshalber tauschen
Jo, danke. Hast recht, vertauscht ist besser (sicherer)!

Geändert von Breager (19. Mär 2012 um 18:12 Uhr)
  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
 
#19

AW: Änderungen von Variablen synchronisieren

  Alt 19. Mär 2012, 20:06
Erklär doch mal, wofür du das MustLock in LockList und UnlockList jeweils veränderst.
Das macht in meinen Augen keinen Sinn.
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
Benutzerbild von Sir Rufo
Sir Rufo

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

AW: Änderungen von Variablen synchronisieren

  Alt 19. Mär 2012, 20:08
Mal noch ne letzte Frage, wenn man in einer Schleife mehrere Items aus der Liste löscht, ist es dann besser, die komplette Schleife zu sprerren oder nur die einzelnen Delete?
Das kommt darauf an, wie lange das jeweils dauert und inwieweit das aus Konsistenzgründen erforderlich sein muss.

Im Allgemeinen gilt, dass die CS sobald als möglich wieder freigegeben wird.
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
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 05:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf