IPC-Semaphore löschen

Post Reply
Message
Author
columbus

IPC-Semaphore löschen

#1 Post by columbus »

Hallo zusammen, ich habe ein Problem mit dem löschen von Semaphoren. Dabei geht es nicht um das eigentliche Löschen, sondern das Nachprüfen, ob noch ein Prozess versucht auf diese Semaphore zuzugreifen. So eine Art waitpid ( der Vergleich hinkt )

Allllsoooo:
ich möchte eine Semaphore löschen, die von mehreren Prozessen genutzt wird. Prozess A erzeugt eine Semaphore, schreibt die Semaphren-ID in eine Datei und macht sich dann an die Arbeit. Prozess B und C öffnen die Datei lesen die Semaphor-Kennung und greifen auf die Semaphore zu. Das klappt alles wunderbar.

Das Problem ist, wenn Prozess A mit seiner Arbeit fertig ist, löscht er die Semaphore wobei aber Prozess B und C immer noch versuchen darauf zuzugreifen.

Ich habe dazu folgende Löschfunktion geschrieben:

Code: Select all

/* Loeschen einer Semaphore                                               */
int loesche_semaphore ( int kennung )
{
  union semun mysem;
  int semnum      = 0,
      rueckgabe_1 = 0,
      rueckgabe_2 = 0;

  while ( 1 )
  {
     if ( ( rueckgabe_1 = semctl ( kennung, semnum, GETZCNT, mysem ) ) == -1 )
     {
         perror ( "Fehler beim bestimmen der Semaphor-Wartelist\n" );
         exit ( errno );
     }
     else if ( ( rueckgabe_2 = semctl ( kennung, semnum, GETNCNT, mysem ) ) == -1 )
     {
         perror ( "Fehler beim bestimmen der Semaphor-Wartelist\n" );
         exit ( errno );
     }
     else
     {
         printf ( "Die Menge der Prozesse ist gleich: %d und %d \n", rueckgabe_1, rueckgabe_2 );
         break;
     }
  }

  if ( ( semctl ( kennung, 0, IPC_RMID, mysem ) ) == -1 )
  {
      perror ( "Fehler beim loeschen der Semaphore\n" );
      exit ( errno );
  }

 return ( 1 );
}
Mit dem Flag GETNCNT bzw GETZCNT kann man laut Doku abfragen, wieviele Prozesse noch auf die Semaphore zugreifen. Mit meiner oben gezeigten Funktion wird aber immer nur 0 Prozesse angezeigt. Sowohl mit GETNCNT als auch mit GETZCNT.
Also wie kann ich feststellen, daß ein oder mehrere Prozesse auf die Semaphore zugreifen?

Ich hoffe ich habe meine Problematik einigermaßen Verständlich wiedergegeben Wink
... und Ihr könnt mir wieder mal helfen.

Vielen Dank im vorraus

Gruss Christian

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#2 Post by Janka »

Die beiden semctl()-Kommando, die du angesprochen hast liefern lediglich die Zahl der Prozesse zurück, die gerade auf die Semaphore *blockieren*. Wenn die Semaphore frei ist (also außerhalb der kritischen Sektionen) ist diese Zahl natürlich 0.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

Columbus

#3 Post by Columbus »

Hast recht. Damit hat es auch nicht funktioniert. Ich habe inzwischen eine andere Lösung.
Ich habe einfach noch eine Semaphore erzeugt, die von jedem Prozess, der auf die erste Semaphore zugreift hochgezählt wird. Wenn dieser Prozess fertig ist, erniedrigt dieser einfach diese zweite Semaphore.

Das klingt jetzt glaube ich ziemlich verwirrend.
Also, ich habe zwei Semaphoren, eine binäre Semaphore und eine Zählsemaphore.
Die binäre Semaphore ist dazu da den Zugriff auf einen kritischen Bereich zu regeln. Dieser kann einfach nur blockiert sein oder frei. Die andere Semaphore ist eine Zählsemaphore. Jeder Prozess, der sich bei der binären Semaphore "anmeldet" also auf den kritischen Bereich zugreifen will, muß zunächst die Zählsemaphore um eins erhöhen. Wenn er fertig ist, setzt er den Wert der Zählsemaphore einfach um eins herab. Wenn kein Prozess mehr auf die binäre Semaphore zugreifen möchte ist die Zählsemaphore gleich Null und kann vom Serverprozess gelöscht werden.

Gruss Christian

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#4 Post by Janka »

Das heißt, du schachtelst einen kritischen Bereich in einen anderen, um einen Frei, und einen Semi-Frei Zustand zu erhalten, ja?

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

columbus

#5 Post by columbus »

Ja!?? Wiso Semi-Frei-Zustand? Wenn alle Clients fertig sind, ist die binäre Semaphore frei. Man kann sie ruhig löschen. Und auch die Zählsemaphore sind vollständig und nicht nur halb frei. Oder habe ich was übersehen?

Gruss Christian Stalp

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#6 Post by Janka »

Wenn ich dich verwirre, vergiss die letzte Anmerkung. Es funktioniert ja, und du weißt warum. Das ist die Hauptsache.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

columbus

#7 Post by columbus »

Nein, das würde mich jetzt schon interessieren, wo ein Problem sein könnte.
Ein Programm ist ja noch nicht gut dadurch daß es irgendwie läuft!

Gruss Christian

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#8 Post by Janka »

Du das Problem nur verlagert: Nun muss nämlich die Zählsemasphore stehenbleiben -- wann darf diese gelöscht werden? Probleme können auch entstehen, wenn ein Prozess abgebrochen wird, während die Zählsemaphore um eins erhöht ist.

Normalerweise löst man das anders: Es gibt einen *Prozesszähler*, der die Prozesse mitzählt, normalerweise in einem Lockfile statt einer Zählsemaphore. Dann baut man einen Signalhandler, der beim Beenden des Prozesses den Prozesszähler erniedrigt.

man flockfile

Jetzt darf aber niemand SIGKILL geben, denn dabei wird kein Handler aufgerufen. Übriggebliebene Ressourcen nach SIGKILL sind aber nicht sooo ungewöhnlich, so dass man das bloß in der Doku erwähnen braucht -- evtl. ein Aufräumprogramm schreiben.

Das Lockfile bleibt übrigens auch stehen -- das ist aber ebenfalls allgemein akzeptiert, wenn in der Doku steht, wo.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

User avatar
columbus
Posts: 5
Joined: 18. Jun 2006 18:03
Location: Mainz

#9 Post by columbus »

Ja aber mit einer Datei hast Du doch genau das gleiche Problem wie mit der Semaphore. Wenn ein Prozess abraucht dann steht in der Datei eine um "1" zu große Zahl.
Und das mit den Signalhandler kann man ja auch mit den Semaphoren machen. Wenn der Prozess abraucht, soll er die Zählsemaphore eins runter zählen. Dann gibt es ja auch noch die Option SEM_UNDO !!! Aber die soll man ja auch nur mit Vorsicht benutzten.

Ich habe jetzt mich ein bischen rumgehört, eine 100% saubere Lösung gibt es da sicher nicht.

Gruss Christian

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#10 Post by Janka »

Nein, eine saubere Lösung dafür ist es, das in die Doku reinzuschreiben.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

Post Reply