Dies ist die alte 4D Dokumentations-Website. Die neue und aktualisierte Dokumentation finden Sie unter developer.4d.com |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
4D v20 R7
Semaphore
|
Semaphore ( Semaphorenname {; ZähleTick} ) -> Funktionsergebnis | ||||||||
Parameter | Typ | Beschreibung | ||||||
Semaphorenname | String |
![]() |
Zu testende und zu setzende Semaphore | |||||
ZähleTick | Lange Ganzzahl |
![]() |
Max. Wartezeit | |||||
Funktionsergebnis | Boolean |
![]() |
Semaphore wurde erfolgreich gesetzt (FALSE) oder Semaphore ist bereits gesetzt (TRUE) | |||||
Eine Semaphore ist ein Flag, das auf Arbeitsstationen oder in Prozessen auf einer Arbeitsstation bekannt ist. Eine Semaphore ist entweder vorhanden oder nicht vorhanden. Die Methoden, die ein Benutzer einsetzt, können testen, ob eine Semaphore vorhanden ist. Eine Semaphore lässt sich nur von der Arbeitsstation oder dem Prozess entfernen, welche(r) sie erstellt hat. Methoden können durch Erstellen und Testen von Semaphoren mit den Arbeitsstationen kommunizieren.
Sie verwenden Semaphoren nicht, um den Zugriff auf Datensätze zu verwalten. Das erledigen 4D und 4D Server automatisch. Sie setzen Semaphoren ein, damit nicht mehrere Benutzer gleichzeitig dieselbe Operation ausführen können.
Die Funktion Semaphore gibt TRUE zurück und führt nichts aus, wenn Semaphorenname vorhanden ist. Ist Semaphorenname nicht vorhanden, legt Semaphore die Semaphore an und gibt FALSE zurück. Eine Semaphore kann immer nur ein Benutzer gleichzeitig erstellen. Wird FALSE zurückgegeben, heißt das einerseits, dass die Semaphore nicht vorhanden war, andererseits aber auch, dass die Semaphore bereits für den Prozess gesetzt wurde, der sie aufgerufen hat.
Semaphore gibt FALSE zurück, wenn keine Semaphore gesetzt wurde bzw. wenn die Semaphore bereits im selben Prozess existiert, in dem der Aufruf erfolgt.
Der Name für eine Semaphore ist auf 255 Zeichen begrenzt, inkl. dem vorangestellten Zeichen $. Längere Namen werden abgeschnitten. Beachten Sie, dass Groß- und Kleinbuchschreibung berücksichtigt wird. Das Programm unterscheidet also zwischen MeineSemaphore und meinesemaphore.
Mit dem optionalen Parameter ZähleTick geben Sie eine Wartezeit in Ticks an, wenn Semaphorenname bereits gesetzt wurde. In diesem Fall wartet die Funktion entweder, bis die Semaphore freigegeben oder die Wartezeit abgelaufen ist und gibt erst dann True zurück.
Es gibt zwei Arten von Semaphoren:
Globale und lokale Semaphoren funktionieren nach derselben Logik. Der Unterschied liegt in ihrer Reichweite. Im Client/Server Modus werden globale Semaphoren von allen Prozessen auf allen Clients und Servern gemeinsam genutzt. Eine lokale Semaphore wird nur von Prozessen auf dem Rechner genutzt, wo sie erzeugt wurde.
In 4D haben globale und lokale Semaphoren dieselbe Reichweite, da es nur einen Benutzer gibt. Wird die Datenbank jedoch in beiden Setups verwendet, stellen Sie sicher, dass - je nachdem, was ausgeführt werden soll - globale oder lokale Semaphoren verwendet werden.
Hinweis: Wir empfehlen, zum Verwalten lokaler Aspekte für den Client einer Anwendung, wie z.B. die Oberfläche oder ein Array mit Interprozessvariablen, lokale Semaphoren zu verwenden. Verwenden Sie dafür globale Semaphoren, verursacht das nicht nur unnötigen Austausch über das Netzwerk, sondern kann auch andere Client-Rechner beeinträchtigen. Über eine lokale Semaphore können Sie solche unerwünschten Nebenwirkungen vermeiden.
Hier eine typische Anweisung zum Verwenden einer Semaphore:
While(Semaphore("MySemaphore";300))
IDLE
End while
// hier durch Semaphore geschützten Code setzen
CLEAR SEMAPHORE("MySemaphore")
In diesem Beispiel wollen Sie verhindern, dass zwei Benutzer gleichzeitig die Preise in einer Produktetabelle global aktualisieren können. Schreiben Sie dazu folgende Methode:
If(Semaphore("UpdatePrices")) ` Versuche die Semaphore zu erstellen
ALERT("Ein anderer Benutzer aktualisiert bereits die Preise global. Versuchen Sie es später wieder.")
Else
DoUpdatePrices ` Aktualisiere alle Preise
CLEAR SEMAPHORE("UpdatePrices")) ` Lösche die Semaphore
End if
Folgendes Beispiel verwendet eine lokale Semaphore. Sie wollen in einer Datenbank mit mehreren Prozessen eine To-do Liste aufrechterhalten. Sie soll in einem Interprozess-Array und nicht in einer Tabelle verwaltet werden. Über eine Semaphore verhindern Sie den gleichzeitigen Zugriff. Für diesen Fall benötigen Sie nur eine lokale Semaphore, da nur ein Arbeitsplatz mit der To-Do Liste arbeitet.
Das Interprozess-Array wird in der Startup Methode initialisiert:
ARRAY TEXT(◊ToDoList;0) ` Die To-Do Liste ist zuerst leer
Mit dieser Methode fügen Sie Einträge in die To-do Liste ein:
` Projektmethode ADD TO DO LIST
` ADD TO DO LIST ( Text )
` ADD TO DO LIST ( Eintrag in To-Do Liste )
C_TEXT($1)
If(Not(Semaphore("$AccessToDoList";300)))
` Warte 5 Sekunden, wenn Semaphore bereits existiert
$vlElem:=Size of array(◊ToDoList)+1
INSERT IN ARRAY(◊ToDoList;$vlElem)
◊ToDoList{$vlElem}:=$1
CLEAR SEMAPHORE("$AccessToDoList") ` Lösche die Semaphore
End if
Obige Methode können Sie von jedem Prozess aus aufrufen.
Diese Methode ermöglicht, eine Methode bei vorhandener Semaphore nicht auszuführen; die Methode informiert die aufrufende Methode mit Fehlernummer und Text.
Syntax:
$L_Error:=Semaphore_proof(->$T_Text_error)
// Schützende Struktur über Semaphoren
C_LONGINT($0)
C_POINTER($1) // Fehlermeldung
// Methode starten
C_LONGINT($L_MyError)
$L_MyError:=1
C_TEXT($T_Sema_local)
$T_Sema_local:="$tictac"
If(Semaphore($T_Sema_local;300))
// Wir haben 300 Ticks gewartet, ohne dass die Semaphore
// von dem, der sie gesetzt hat, freigegeben wurde:
// wir beenden hier
$L_MyError:=-1
Else
// Diese Methode startet nur von einem Prozess gleichzeitig
// Wir haben die Semaphore, wie eingegeben, gesetzt
// so sind wir die einzigen, die sie entfernen können
// Etwas ausführen
...
// Dann durch Entfernen der Semaphore beenden
CLEAR SEMAPHORE($T_Sema_local)
End if
C_TEXT($T_Message)
If($L_MyError=-1)
$T_Message:="Die Semaphore "+$T_Sema_local+" hat den Zugriff auf den restlichen Code blockiert"
Else
$T_Message:="OK"
End if
$0:=$L_MyError
$1->:=$T_Message // Die aufrufende Methode empfängt Fehlernummer und Erläuterung in einfachem Text.
Produkt: 4D
Thema: Prozess (Kommunikation)
Nummer:
143
Geändert: 4D v11 SQL
4D Programmiersprache ( 4D v20 R7)