AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

Ein Thema von Der schöne Günther · begonnen am 25. Jul 2019 · letzter Beitrag vom 29. Jul 2019
Antwort Antwort
Seite 1 von 2  1 2   
Der schöne Günther

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

Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

  Alt 25. Jul 2019, 13:24
Delphi-Version: 10 Seattle
Ich suche etwas wo man Zugriff auf eine geschützte Resource anfordern kann, und wenn man Zugriff bekommt danach die Sperre wieder frei machen muss.

Alles was ich finde (kritische Abschnitte, Semaphore, Monitor, …) liegt in System oder System.SyncObjs, bezieht sich aber auf Threads. Bei all diesen Implementationen meint er es gut einen Deadlock zu verhindern indem man problemlos sagen kann:

Delphi-Quellcode:
someMutex.Acquire();
someMutex.Acquire();
ShowMessage('Das hier sollte nie zu sehen sein');
Ich suche etwas wo ich sagen kann "TryLock" und er sagt mir "ja/nein". Und dass er mir bitte "Nein" sagt wenn ich im gleichen Thread schon einmal gelocked habe.

Gibt es da etwas in der Standard-Bibliothek? Ich finde nichts.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
8.796 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

  Alt 25. Jul 2019, 13:44
Das ist jetzt vermutlich zu trivial:
Delphi-Quellcode:
type
  TLock = record
  private
    FLocked: Boolean;
    class function Create: TLock; static;
  public
    function TryLock: Boolean;
    procedure Unlock;
    property Locked: Boolean read FLocked;
  end;

class function TLock.Create: TLock;
begin
  Result.FLocked := False;
end;

function TLock.TryLock: Boolean;
begin
  Result := not FLocked;
  FLocked := True;
end;

procedure TLock.Unlock;
begin
  FLocked := False;
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Der schöne Günther

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

AW: Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

  Alt 25. Jul 2019, 13:56
Ja schon ein bisschen 😉
Das ist ja im Endeffekt wie eine globale Boolean-Variable an die jeder dran darf. Ich hätte mir schon vorgestellt dass man es nur unlocken kann wenn man es selbst vorher gelocked hat.

Wenn es nichts gibt bastele ich mir etwas und frage nach Feedback sobald ich fertig bin. Auf die Schnelle kenne ich in den Bibliotheken anderer Sprachen auch nichts...
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.165 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

  Alt 25. Jul 2019, 14:01
Ich hätte mir schon vorgestellt dass man es nur unlocken kann wenn man es selbst vorher gelocked hat.
Wenn sich alles in einem Thread abspielt ist alles/jeder "man selbst". Wie definierst du dieses "selbst"?
Im Prinzip müsstest du dem Lock() einen (zufälligen?) Wert übergeben den nur die Methode die das Lock() aufgerufen hat lokal kennt und der dann quasi als eine Art "Password" für das Unlock() fungiert.

Also Uwe's Klasse erweitert:
Delphi-Quellcode:
type
  TLock = record
  private
    FLocked: Boolean;
    FPW: Integer;
    class function Create: TLock; static;
  public
    function TryLock(APW: Integer): Boolean;
    function Unlock(APW: Integer): Boolean;
    property Locked: Boolean read FLocked;
  end;

class function TLock.Create: TLock;
begin
  Result.FLocked := False;
end;

function TLock.TryLock(APW: Integer): Boolean;
begin
  Result := not FLocked;
  if (Result) then
  begin
    FLocked := True;
    FPW := APW;
  end;
end;

procedure TLock.Unlock(APW: Integer);
begin
  Result := APW = FPW;
  if Result then
    FLocked := False;
end;
Edit: Uwe's Erweiterung unten ist sogar noch einen Tick eleganter
V
V
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."

Geändert von Neutral General (25. Jul 2019 um 14:16 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
8.796 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

  Alt 25. Jul 2019, 14:12
dass man es nur unlocken kann wenn man es selbst vorher gelocked hat.
Wer ist denn selbst bzw. wie identifiziert sich dieses selbst? Man kann sich natürlich beim Lock auch einen Syhlüssel zum Unlock geben lassen:
Delphi-Quellcode:
  TLock = record
  private
    FLocked: TGUID;
    class function Create: TLock; static;
    function GetLocked: Boolean;
  public
    function TryLock(var Key: TGUID): Boolean;
    function Unlock(const Key: TGUID): Boolean;
    property Locked: Boolean read GetLocked;
  end;

class function TLock.Create: TLock;
begin
  Result.FLocked := TGUID.Empty;
end;

function TLock.GetLocked: Boolean;
begin
  Result := (FLocked <> TGUID.Empty);
end;

function TLock.Unlock(const Key: TGUID): Boolean;
begin
  Result := False;
  if Key = FLocked then begin
    FLocked := TGUID.Empty;
    Result := True;
  end;
end;

function TLock.TryLock(var Key: TGUID): Boolean;
begin
  Result := False;
  if not Locked then begin
    Key := TGUID.NewGuid;
    FLocked := Key;
    Result := True;
  end;
end;
Das scheint aber schon eine sehr spezielle Anforderung zu sein, die du da umsetzen willst.

Ich sehe gerade, da hat das schon jemand aufgegriffen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Der schöne Günther

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

AW: Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

  Alt 25. Jul 2019, 14:15
Wenn sich alles in einem Thread abspielt
Das habe ich nicht gesagt. Multithreading-fähig muss das natürlich schon sein.

Im Prinzip müsstest du dem Lock() einen (zufälligen?) Wert übergeben den nur die Methode die das Lock() aufgerufen hat lokal kennt und der dann quasi als eine Art "Password" für das Unlock() fungiert.
Man kann sich natürlich beim Lock auch einen Syhlüssel zum Unlock geben lassen
Richtig, nur dass ich keine GUID oder Integer nehmen würde sondern eine Interface-basierte Referenz die dafür sorgt dass spätestens dann Unlock() gemacht wird wenn man die Referenz wegwirft und man vergessen hat aufzuschließen.


Ich denke im Groben habe ich jetzt auch etwas, das Interface ist ungefähr so:

Delphi-Quellcode:
   ELockException = class(Exception);
   ELockNotHeldException = class(ELockException);

   ILock = interface
   ['{57CCCDE4-63F8-41F6-A6F0-39B4159B06FF}']
      /// <exception cref="ELockNotHeldException" />
      procedure UnLock();
   end;

   ILockableResource = interface
   ['{88085418-BD27-4B5D-AD00-B456C8E017A7}']
      function TryLock(
         out lock: ILock;
         const timeout: TTimeSpan
      ): Boolean; overload;
      function TryLock(out lock: ILock): Boolean; overload;
   end;
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
8.796 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

  Alt 25. Jul 2019, 14:21
Ich suche etwas wo man Zugriff auf eine geschützte Resource anfordern kann, und wenn man Zugriff bekommt danach die Sperre wieder frei machen muss.
Ich suche etwas wo ich sagen kann "TryLock" und er sagt mir "ja/nein". Und dass er mir bitte "Nein" sagt wenn ich im gleichen Thread schon einmal gelocked habe.
Ich hätte mir schon vorgestellt dass man es nur unlocken kann wenn man es selbst vorher gelocked hat.
Multithreading-fähig muss das natürlich schon sein.
die dafür sorgt dass spätestens dann Unlock() gemacht wird wenn man die Referenz wegwirft und man vergessen hat aufzuschließen.
Deine Spezifikationen vermehren sich mit jedem Post
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Der schöne Günther

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

AW: Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

  Alt 25. Jul 2019, 14:33
Stimmt

Ich glaube es ist Zeit für eine Pause 🏖 🍧
  Mit Zitat antworten Zitat
einbeliebigername

Registriert seit: 24. Aug 2004
130 Beiträge
 
Delphi XE8 Professional
 
#9

AW: Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

  Alt 25. Jul 2019, 14:58
Hallo,

bevor du was selbst programmierst, erkläre noch mal an einem Beispile was du brauchst. Denn wenn du in einem Thread
Delphi-Quellcode:
  x.Acquire;
  try
    x.Acquire;
    try
      Do;
    finally
      x.Release;
    end;
  finally
    x.Release;
  end;
hast, kann er doch nur entweder das Do ausführen oder den Thread für immer blockieren.

Es gibt bei einigen noch ein function TryEnter: Boolean . Vieleicht hilft das.
Mit freundlichen Grüßen, einbeliebigername.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
8.796 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Lock/Unlock-Mechanismus ohne Bezug auf Multithreading?

  Alt 25. Jul 2019, 16:05
Es gibt bei einigen noch ein function TryEnter: Boolean . Vieleicht hilft das.
Das TryEnter läuft aber positiv durch, wenn es mehrfach im selben Thread aufgerufen wird. Das widerspricht einer Anforderung.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

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