Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Zugriff auf globales Object in CriticalSection? (https://www.delphipraxis.net/121248-zugriff-auf-globales-object-criticalsection.html)

Win32.API 24. Sep 2008 16:03


Zugriff auf globales Object in CriticalSection?
 
Hallo,

ich habe ein globales Object der Klasse TLog, nun kann es passieren das mehrere Threads gleichzeitig <TLog>.Log() aufrufen.
Muss ich die Zugriffe auf <TLog>.X() mit einer Criticalsection schuetzen?

TLog.Log() sieht so aus:


Delphi-Quellcode:
procedure TLog.Log(..);
begin
  EnterCriticalSection(lpLogCS);
  try
    FFileStream.Write(szLog[1], length(szLog));
  finally
    LeaveCriticalSection(lpLogCS);
  end;
end;
Meine Intuition sagt mit, dass ich dies nicht muss da ich nur lesend drauf zugreife, stimmt das?


Gruß,
Win32.API

SubData 24. Sep 2008 16:16

Re: Zugriff auf globales Object in CriticalSection?
 
Den Zugriff auf .Log selbst brauchst du nicht in eine CriticalSection packen.
In der Prozedur wird ja sowieso eine CriticalSection verwendet um den schreibenden Teil zu schützen.

Elvis 24. Sep 2008 16:44

Re: Zugriff auf globales Object in CriticalSection?
 
Ist es eine globale-globale ( :mrgreen: ) Variable oder eine variable, die nur in der Implementation einer Unit steckt?
Wenn letzteres, ann könntest du ja eine Funktion zur Verfügung stellen, die lesenden Zugriff auf das Log gewährt.

Den globale variablen, die jeder lesen und schreiben kann sind ziemlicher Mist, denn die kannst du gar nicht absichern.

Grob vereinfacht, wäre sowas hier möglich:
Delphi-Quellcode:
type
  TLog = class
  ...
  public
    procedure Log(...); virtual; abstract;
    class function GetLog : TLog;
    class procedure RegisterLogHandler(logHandler : TLog);
  end;

implementation
var
  globalLogInstance : TLog

type
  TAggregatedLog = class(TLog)
  ...
  public
    property LogHandlers : TObjectList...;
    procedure Log(...); override;
    ...
  end;

...

class procedure TAggregatedLog.RegisterLogHandler(logHandler : TLog);
begin
  EnterCriticalSection(lpLogCS);
  try
    LogHandlers[i].Add(logHandler);
  finally
    LeaveCriticalSection(lpLogCS);
  end;
end;

procedure TAggregatedLog.Log(...) : TLog;
var
  i : Integer;
begin
  EnterCriticalSection(lpLogCS);
  try
    for i := 0 LogHandlers.Count - 1 do
      Tlog(LogHandlers[i]).Log(...);
  finally
    LeaveCriticalSection(lpLogCS);
  end;
end;

class function GetLog : TLog;
begin
  result := globalLogInstance;
end;

initialization
  globalLogInstance := TAggregatedLog.Create();
finalization
  globalLogInstance.Free();
end.
einmal so verpackt, könntest du beliebige Logger zur laufzeit registrieren.
Und die Instanz in der Unit würde mit allen einen Log-Eintrag generieren, ohne dass der zu benutzende Code etwas davn wissen muss. (Zum Bleistift Eventlog, Dateilog, Kommandozeile, email, ...)

Da du jetzt keine öffentlich beschreibare globale Variable nutzt, könntest du dann in der Methode zum Registrieren die gleiche CriticalSection nutzen. Einfach um sicher zu stellen, dass nix halbes ausgeführt wird.

Aber wozu der Stress, ich dachte es gibt bereits ein LogForDelphi?

Win32.API 24. Sep 2008 17:05

Re: Zugriff auf globales Object in CriticalSection?
 
Danke fuer die Antworten,

es Handelt sich hierbei um globale Instazen von TThread-Objekten die in der Unit uGlobal, im Interface-Abschnitt, deklariert sind (Das Beispiel mit der Log Funktion war schlecht gewaehlt).

Nun sollen andere Threads den Thread-Objekten neue Aufgaben hinzufuegen koennen (<Thread1>.AddJob(...)). So wie ich das jetzt verstanden habe ist es nicht zwingend erforderlich dies in Criticalsections zu tun. Solange _Niemand_ etwas ohne Synchronisation schreibt sollte es keine Probleme geben.


Gruß,
Win32.API


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:52 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