ReadWriteLock
Verfasst: 22.08.2009 10:14
Servus.
Hier mal schnell ein Include für einen RW - Lock geschrieben. Der Lock ermöglicht shared und exclusiven Zugriff. Z.B. können dann beliebig viele Threads eine Ressource im Shared Mode lesen, will ein Thread an der Ressource etwas ändern bekommt er exclusiven Zugriff und alle anderen Thread müssen warten bis er fertig ist.
Vielleicht kanns ja jemand brauchen.
Gruß, Alex
Hier mal schnell ein Include für einen RW - Lock geschrieben. Der Lock ermöglicht shared und exclusiven Zugriff. Z.B. können dann beliebig viele Threads eine Ressource im Shared Mode lesen, will ein Thread an der Ressource etwas ändern bekommt er exclusiven Zugriff und alle anderen Thread müssen warten bis er fertig ist.
Vielleicht kanns ja jemand brauchen.
Gruß, Alex
Code: Alles auswählen
; ------------------------------------------------------------------------------------
; ReadWrite Lock
; Mutex mit Shared & Excluiven Zugriff
; PB 4.3 +, All Os, Ascii/Unicode, x86/x64
; Author: Alexander Aigner
; ------------------------------------------------------------------------------------
; EnableExplicit
; ------------------------------------------------------------------------------------
; Internal
; ------------------------------------------------------------------------------------
Structure RWL_Data
ReaderCount.i
ThreadsWaiting.i
ResumeSignal.i
LastReaderSignal.i
Writer.i
Mutex.i
EndStructure
Macro _RWL_CheckForWriter(_RWL)
If _RWL#\Writer
_RWL#\ThreadsWaiting + 1
UnlockMutex(_RWL#\Mutex)
WaitSemaphore(_RWL#\ResumeSignal)
LockMutex(_RWL#\Mutex)
_RWL#\ThreadsWaiting-1
EndIf
EndMacro
; ------------------------------------------------------------------------------------
; Public
; ------------------------------------------------------------------------------------
; Neuen RWLock erstellen
Procedure RWL_New()
Protected *RWL.RWL_Data
*RWL = AllocateMemory(SizeOf(RWL_Data))
With *RWL
\Mutex = CreateMutex()
\ResumeSignal = CreateSemaphore()
\LastReaderSignal = CreateSemaphore()
EndWith
ProcedureReturn *RWL
EndProcedure
; RWLock freigeben
Procedure RWL_Free(*RWL.RWL_Data)
With *RWL
FreeMutex(\Mutex)
FreeSemaphore(\ResumeSignal)
FreeSemaphore(\LastReaderSignal)
FreeMemory(*RWL)
EndWith
EndProcedure
; Shared - Zugriff anfordern
Procedure RWL_LockShared(*RWL.RWL_Data)
With *RWL
LockMutex(\Mutex)
_RWL_CheckForWriter(*RWL) ; Prüfen ob Exclusiver Zugriff offen
\ReaderCount + 1 ; Ein Reader mehr
UnlockMutex(\Mutex)
EndWith
EndProcedure
; Shared Zugriff freigeben
Procedure RWL_UnlockShared(*RWL.RWL_Data)
With *RWL
LockMutex(\Mutex)
\ReaderCount-1 ; Ein Reader weniger
If \ReaderCount<0 ; Kleiner Schutz gegen falsche Verwendung
\ReaderCount = #Null
EndIf
If \Writer And \ReaderCount = #Null
SignalSemaphore(\LastReaderSignal) ; Fertig Signal für Exclusiven Zugriff
EndIf
UnlockMutex(\Mutex)
EndWith
EndProcedure
; Exclusiven Zugriff anfordern
Procedure RWL_LockExclusive(*RWL.RWL_Data)
With *RWL
LockMutex(\Mutex)
_RWL_CheckForWriter(*RWL) ; Prüfen ob Exclusiver Zugriff offen
\Writer = #True ; Exclusiv öffnen
UnlockMutex(\Mutex)
If \ReaderCount
WaitSemaphore(\LastReaderSignal) ; Warten biss alle shared fertig
EndIf
EndWith
EndProcedure
; Exclusiven Zugriff freigeben
Procedure RWL_UnlockExclusive(*RWL.RWL_Data)
Protected i
With *RWL
LockMutex(\Mutex)
\Writer = #False ; Exclusiv schließen
For i = 1 To \ThreadsWaiting
SignalSemaphore(\ResumeSignal) ; Wartende Zugiffe fortsetzen
Next
UnlockMutex(\Mutex)
EndWith
EndProcedure