System.SyncObjs.TLightweightMREW

De RAD Studio API Documentation
Aller à : navigation, rechercher

Delphi

  TLightweightMREW = record
{$IFDEF MACOS}
  private
    class var CalendarClock: clock_serv_t;
{$ENDIF MACOS}
  private
{$IFDEF MSWINDOWS}
    FNativeRW: SRWLOCK;
{$ENDIF MSWINDOWS}
{$IFDEF POSIX}
    FNativeRW: pthread_rwlock_t;
    procedure GetPosixEndTime(var EndTime: timespec; TimeOut: Cardinal); inline;
{$ENDIF POSIX}
  public
{$IFDEF MACOS}
    class constructor Create;
    class destructor Destroy;
{$ENDIF MACOS}
    [HPPGEN('TLightweightMREW() { _op_Initialize(*this); }' + #13#10#13#10#9 +
            'static void __fastcall _op_Initialize(/* out */ TLightweightMREW &Dest)')]
    class operator Initialize(out Dest: TLightweightMREW);
    procedure BeginRead;
    function TryBeginRead: Boolean; {$IF defined(LINUX) or defined(ANDROID)}overload;{$ENDIF}
{$IF defined(LINUX) or defined(ANDROID)}
    function TryBeginRead(Timeout: Cardinal): Boolean; overload;
{$ENDIF LINUX or ANDROID}
    procedure EndRead;
    procedure BeginWrite;
    function TryBeginWrite: Boolean; {$IF defined(LINUX) or defined(ANDROID)}overload;{$ENDIF}
{$IF defined(LINUX) or defined(ANDROID)}
    function TryBeginWrite(Timeout: Cardinal): Boolean; overload;
{$ENDIF LINUX or ANDROID}
    procedure EndWrite;
  end;

C++

struct DECLSPEC_DRECORD TLightweightMREW
{
private:
    _RTL_SRWLOCK FNativeRW;
public:
    TLightweightMREW() { _op_Initialize(*this); }
        static void __fastcall _op_Initialize(/* out */ TLightweightMREW &Dest);
    void __fastcall BeginRead();
    bool __fastcall TryBeginRead();
    void __fastcall EndRead();
    void __fastcall BeginWrite();
    bool __fastcall TryBeginWrite();
    void __fastcall EndWrite();
};

Propriétés

Type Visibilité  Source Unité  Parent
record
struct
public
System.SyncObjs.pas
System.SyncObjs.hpp
System.SyncObjs System.SyncObjs


Enregistrement TLightweightMREW

TLightweightMREW est une implémentation de verrou en lecture/écriture introduite dans RAD Studio 10.4.1, qui fonctionne sur toutes les plates-formes prises en charge pour plus de rapidité et de souplesse que l'implémentation TMultiReadExclusiveWriteSynchronizer existante.

Ce synchronisateur est implémenté comme un enregistrement managé (et non comme une classe, de sorte qu'il n'est pas nécessaire de le libérer de la mémoire). Ses besoins en mémoire sont plus limités et il est généralement plus rapide, car il incorpore des API POSIX natives.

Le TLightweightMREW est beaucoup plus rapide que le TMultiReadExclusiveWriteSynchronizer et implémente un mécanisme de verrouillage en lecture/écriture sur toutes les plates-formes tandis que le TMultiReadExclusiveWriteSynchronizer est implémenté comme une section critique sur les plates-formes autres que Windows. C'est pourquoi dans la plupart des cas, il est préférable d'utiliser le TLightweightMREW pour remplacer le TMultiReadExclusiveWriteSynchronizer classique.

TLightweightMREW, modes d'accès

Le TLightweightMREW incorpore une implémentation native d'un verrou en lecture/écriture (également appelé verrou MRSW ou verrou MREW). Ce mécanisme autorise deux "modes" d'accès différents : l'accès partagé en lecture et l'accès exclusif en écriture.

Accès partagé

  • L'accès partagé permet à plusieurs lecteurs d'accéder à la ressource en même temps, tout en empêchant les threads d'acquérir un accès exclusif (en écriture).
  • L'accès partagé peut être demandé de façon récursive. Un thread unique peut l'acquérir plusieurs fois d'affilée. A chaque appel à la méthode BeginRead/TryBeginRead doit correspondre un appel à EndRead.

Accès exclusif

  • L'accès exclusif (en écriture) ne peut être accordé qu'à un thread à la fois. Lorsqu'un verrou TLighweightMREW est en mode exclusif, il empêche tout thread d'obtenir un accès partagé (en lecture).
  • L'accès exclusif ne peut pas être demandé de façon récursive.
  • L'accès partagé ne peut pas être mis à niveau vers un accès exclusif.

Utilisation de TLightweightMREW sur les plates-formes prises en charge

Alors que l'implémentation de TLightweightMREW est dépendante du système d'exploitation, ces fonctions de verrou sont quasiment identiques sur toutes les plates-formes prises en charge.

Les faits suivants sont valables pour toutes les implémentations :

  • Si un thread contient un verrou en lecture, n'importe quel autre thread peut également acquérir un verrou en lecture, mais aucun ne peut acquérir un verrou en écriture.
  • Si un thread contient un verrou en écriture, aucun thread ne peut acquérir un verrou en lecture ou en écriture.
  • Si un thread détient un verrou en lecture, il peut acquérir un autre verrou en lecture avant que le premier soit libéré (récursion).
  • Si un thread détient un verrou en écriture, il ne peut pas acquérir un autre verrou en écriture.

Le comportement suivant dépend du système d'exploitation :

  • Si au moins un lecteur est toujours actif, un concepteur n'obtient jamais le verrou (privation).
  • Si le même thread essaie d'acquérir deux fois un verrou en écriture de façon récursive, l'application produit un verrou mortel sur Windows mais déclenche une exception sur les systèmes POSIX.