Beispiel24: Semaphoren
Dieser Artikel beschreibt die Verwendung von Semaphoren.
- 1. Entpacken Sie die heruntergeladene ZIP-Datei.
- 2. Öffnen Sie die enthaltene zip-Datei in TwinCAT 3 mit einem Klick auf Open Project ….
- 3. Wählen Sie Ihr Zielsystem aus.
- 4. Bauen Sie das Beispiel auf Ihrer lokalen Maschine (z.B. Build->Build Solution).
- 5. Beachten Sie die unter Konfiguration auf dieser Seite aufgeführten Handlungsschritte.
- 6. Aktivieren Sie die Konfiguration mit einem Klick auf .
- Das Beispiel ist einsatzbereit.
Beschreibung
Das Beispiel enthält einen „LargeObjPool“, der zwei „LargeObj“ zur Bearbeitung durch die „LargeObjProcessors“ enthält.
Die „LargeObjProcessors“ werden dabei durch unterschiedliche Tasks mit unterschiedlichen Prioritäten und auf unterschiedlichen Cores der CPU angesteuert. Sie zählen in der Info-Dataarea mit, wie häufig eine Bearbeitung durchgeführt werden konnte („Info->ProcessedObjCount“) und wie häufig kein Objekt zur Bearbeitung innerhalb der Wartezeit bereitstand („Info->TakeObjFailedCount“).
Das Beispiel verstehen
Der LargeObjPool wird in der PS-Transition durch die InitPool()
-Methode mit zwei LargeObj (definiert über den Parameter „ObjCount“) initialisiert. Der Pool bietet im Wesentlichen zwei Methoden an, die durch die „LargeObjProcessors“ genutzt werden:
TakeObj()
liefert ein LargeObj zurück, falls eins bereit steht. Dabei wird durch eine Semaphore bis zu einem Timeout gewartet, ob ein Objekt bereitgestellt wird. Die Objekte selbst sind dabei in einer Map gehalten, wobei die Zugriffe auf die Map durch eine CriticalSection geschützt sind.ReturnObj()
stellt ein Objekt nach der Bearbeitung wieder in dem Pool zur erneuten Bearbeitung bereit.
LargeObjProcessor verwendet in seiner CycleUpdate()
TakeObj()
des Pools um ein LargeObj zur Bearbeitung zu bekommen. Falls dieses erfolgreich ist, wird eine Verarbeitung durch die Hilfsfunktion ConsumeTime()
simuliert bevor das LargeObj mittels ReturnObj()
an den Pool zurückgegeben wird.
Damit das Runterfahren des Systems sichergestellt werden kann, dürfen keine LargeObj mehr in Bearbeitung sein. Dieses wird erreicht, indem der LargeObjPool mittels TcTryLockOpState()
und TcReleaseOpState()
dem TwinCAT System mitteilt, dass ein Objekt in Bearbeitung ist. Solange der hinterlegte Zähler nicht 0 ist, wird das TcCOM-Objekt „Pool“ zurückgestellt und erst später durch die Op->SafeOp Transition runtergefahren.