Hinweis: Das Forum wird geschlossen! Neue Registrierungen sind nicht mehr möglich!

 Zurück zu Pro-Linux   Foren-Übersicht   FAQ     Suchen    Mitgliederliste
IPC-Semaphore löschen

 
Neuen Beitrag schreiben   Auf Beitrag antworten    Pro-Linux Foren-Übersicht -> Programmieren - C
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
columbus
Gast





BeitragVerfasst am: 09. Mai 2006 17:00   Titel: IPC-Semaphore löschen

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:
/* 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
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 09. Mai 2006 23:50   Titel:

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.
 
Benutzer-Profile anzeigen Private Nachricht senden

Columbus
Gast





BeitragVerfasst am: 06. Jun 2006 16:20   Titel:

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
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 07. Jun 2006 0:27   Titel:

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.
 
Benutzer-Profile anzeigen Private Nachricht senden

columbus
Gast





BeitragVerfasst am: 14. Jun 2006 13:18   Titel:

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
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 14. Jun 2006 22:59   Titel:

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.
 
Benutzer-Profile anzeigen Private Nachricht senden

columbus
Gast





BeitragVerfasst am: 18. Jun 2006 16:56   Titel:

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
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 19. Jun 2006 9:34   Titel:

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.
 
Benutzer-Profile anzeigen Private Nachricht senden

columbus



Anmeldungsdatum: 18.06.2006
Beiträge: 5
Wohnort: Mainz

BeitragVerfasst am: 23. Jun 2006 14:48   Titel:

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
 
Benutzer-Profile anzeigen Private Nachricht senden

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 23. Jun 2006 21:44   Titel:

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.
 
Benutzer-Profile anzeigen Private Nachricht senden

Beiträge vom vorherigen Thema anzeigen:   
     Pro-Linux Foren-Übersicht -> Programmieren - C Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehen Sie zu:  

Powered by phpBB © phpBB Group
pro_linux Theme © 2004 by Mandaxy