Programmieren mit C++

Visual C++

Systemnahe Lösungen mit VC++

Semaphoren inspizieren

Kann man den Wert einer Semaphore abfragen, ohne daß die Semaphore über ReleaseSemaphore() freigegeben und damit der Wert verändert wird?

Frage

Normalerweise kann der Wert einer „lebenden“ Semaphore nicht abgefragt werden, ohne nicht zuvor ReleaseSemaphore() aufzurufen. Das Win32 API kennt keine offizielle Funktion für diesen Zweck. Allerdings gibt es speziell unter NT die Bibliothek NTDLL.DLL, die einen Aufruf kennt, der eine Semaphore abfragen kann.

NTSTATUS WINAPI NtQuerySemaphore(
     HANDLE     Handle, 
     UINT       InfoClass, 
     PSEMAINFO  SemaInfo, 
     UINT       InfoSize,
     PUINT      RetLen );

Neben dem Handle der Semaphore ist der Funktion NtQuerySemaphore in InfoClass der Wert

#define SEMAQUERYINFOCLASS  0

zu übergeben. SemaInfo nimmt einen Zeiger auf eine SEMAINFO-Struktur auf, die wie folgt definiert ist:

Lösung

typedef struct _SEMAINFO {
  UINT  Count;     // Aktueller Zählerstand
  UINT  Limit;     // Maximaler Zähler
} SEMAINFO, *PSEMAINFO;

Der Parameter InfoSize spezifiziert die Größe der Struktur SemaInfo, während die Funktion in RetLen die Größe der zurückgelieferten Informationen returniert. Da diese Funktion noch einigen Overhead beinhaltet, der nicht unbedingt notwendig ist, implementiert die Funktion QuerySemaphore eine vereinfachte Schnittstelle, der lediglich das Handle der Semaphore zu übergeben ist, sowie ein Zeiger auf einen long, in dem die Funktion den Wert der Semaphore ablegt. Als Funktionsergebnis returniert QuerySemaphore() den Erfolgsstatus des Aufrufs.

Struktur SEMAINFO

BOOL WINAPI QuerySemaphore(
    HANDLE  hSemaphore,
    LPLONG  lpCount)
{
  SEMAINFO    SemInfo;
  UINT        RetLen;
  NTSTATUS    Status;

Intern setzt die Funktion alle obligatorischen Felder für den Aufruf der Funktion NtQuerySemaphore() und fragt den Rückgabewert der Funktion ab und setzt diesen auf ein boolsches Ergebnis um.

  Status = NtQuerySemaphore( 
      hSemaphore, 
      SEMAQUERYINFOCLASS, 
      &SemInfo, 
      sizeof SemInfo,
      &RetLen);
  if( !NT_SUCCESS(Status) )
  {
    *lpCount = -1;
    return FALSE;
  }
  else {
     *lpCount = SemInfo.Count;
     return TRUE;
  }
}

Zum Einlinken der Funktion kann auf die Headerdateien NATIVE.H und QuerySemaphore.h zurückgegriffen werden, so daß nicht die gesamte Bibliothek ntdll.lib zum Linken notwendig ist.

Da die Funktion QuerySemaphore() letztlich nur eine Hülle um die Funktion NtQuerySemaphore der Bibliothek NTDLL.DLL bildet, steht diese Funktion jedoch nur unter Windows NT zur Verfügung.

Ein Beispiel für das Einbinden und Anwenden der Funktion wird nachfolgend aufgezeigt. Zunächst wird die Semaphore erzeugt.

#include "QuerySemaphore.h"
 
LONG Value;
 
// Semaphore erzeugen
HANDLE Handle = CreateSemaphore(NULL, 4, 10, NULL);

Abschließend kann der Wert der Sempahore abgefragt werden.

// Inhalt der Semaphore abfragen
QuerySemaphore(Handle, &Value);

Die Abfrage ist natürlich auch während der Lebensdauer der Semaphore möglich, denn der Einsatz der Semaphore macht ja erst bei asynchronem Programmablauf Sinn.

// Semaphore abwarten
WaitForSingleObject(Handle, INFINITE);
 
// Inhalt der Semaphore erneut abfragen 
QuerySemaphore(Handle, &Value);

Funktion QuerySemaphore





Sachgebiet


© 2009-2012 by Alojado Publishing. Alle Rechte vorbehalten. Ausgewiesene Marken gehören ihren jeweiligen Eigentümern.
Mit der Benutzung dieser Seite erkennen Sie die Nutzungsbedingungen und die Datenschutzerklärung an. Der Betreiber übernimmt keine Haftung für den Inhalt verlinkter externer Internetseiten.
Seite erzeugt 2012-05-20 03:10:35 von textarchiv.alojado.de