TestAndSet
Mit der Funktion können Sie ein Flag prüfen und setzen, ohne dass dies unterbrochen werden kann. Dadurch können Datenzugriffe synchronisiert werden. Mit TestAndSet kann die Funktionsweise eines Semaphors erreicht werden.
Bei erfolgreichem Funktionsaufruf liefert die Funktion TRUE zurück und auf die gewünschten Daten darf zugegriffen werden. Bei erfolglosem Funktionsaufruf liefert die Funktion FALSE zurück und auf die gewünschten Daten darf nicht zugegriffen werden. In diesem Fall muss applikativ eine Alternativbehandlung vorgesehen werden.
Ein-/Ausgänge
VAR_IN_OUT
Flag : BOOL; (* Flag to check if TRUE or FALSE *)
END_VAR
Name | Typ | Beschreibung |
---|---|---|
Flag | BOOL | Boolesches Flag, das geprüft wird
|
Beispiel
VAR_GLOBAL
bGlobalTestFlag : BOOL;
END_VAR
VAR
nLocalBlockedCounter : DINT;
END_VAR
IF TestAndSet(GVL.bGlobalTestFlag) THEN
(* bGlobalTestFlag was FALSE, nobody was blocking, NOW
bGlobalTestFlag is set to TRUE and blocking others *)
(* ... *)
(* remove blocking by resetting the flag *)
GVL.bGlobalTestFlag := FALSE;
ELSE
(* bGlobalTestFlag was TRUE, somebody is blocking *)
nLocalBlockedCounter := nLocalBlockedCounter + 1;
(* ... *)
END_IF
NEGATIV-Beispiel
Vorsicht ist bei einer weiteren Kapselung, z. B. in einem Funktionsbaustein, geboten, da dies die gewünschte atomare Operation zunichtemachen kann. Eine sichere Synchronisierung von Datenzugriffen kann dann nicht mehr erfolgen. Im Folgenden ist ein NEGATIV-Beispiel eingefügt, welches zeigt, wie die Funktion NICHT verwendet werden darf. Sollten bei dieser Implementierung zwei Kontexte zugleich Zugriff erbitten, so könnten beide davon ausgehen, dass der Zugriff erlaubt ist und es würde ein zeitgleicher, ungesicherter Zugriff auf die Daten stattfinden.
FUNCTION_BLOCK FB_MyGlobalLock
VAR_INPUT
bLock : BOOL; // set TRUE to lock & set FALSE to unlock
END_VAR
VAR_OUTPUT
bLocked : BOOL;
END_VAR
IF bLock THEN
TestAndSet(bLocked);
ELSE // unlock
bLocked := FALSE;
END_IF
IF NOT GVL.fbGlobalLock.bLocked THEN
GVL.fbGlobalLock(bLock := TRUE);
(* ... *)
GVL.fbGlobalLock(bLock := FALSE);
END_IF
Mit dem Funktionsbaustein FB_IecCriticalSection wird die Verwendung von kritischen Bereichen als alternatives Mutex-Verfahren angeboten. |
Voraussetzungen
Entwicklungsumgebung | Zielplattform | Einzubindende SPS-Bibliotheken (Kategoriegruppe) |
---|---|---|
TwinCAT v3.1.0 | PC oder CX (x86, x64, ARM) | Tc2_System (System) |