2013-03-01 2 views
11

Ich bin etwas verwirrt von der Linux-API sem_unlink(), vor allem, wenn oder warum ich es nennen soll. Ich habe Semaphore in Windows seit vielen Jahren verwendet. Wenn Sie in Windows das letzte Handle eines benannten Semaphors schließen, entfernt das System das zugrunde liegende Kernel-Objekt. Aber unter Linux scheint der Entwickler das Kernel-Objekt durch Aufruf von sem_unlink() entfernen zu müssen. Wenn das Kernel-Objekt nicht vorhanden ist, bleibt es im Ordner/dev/shm erhalten.Wann sem_unlink() aufrufen?

Das Problem, auf das ich stoße, wenn Prozess A sem_unlink() aufruft, während Prozess B den Semaphor gesperrt hat, zerstört es sofort den Semaphor und jetzt ist Prozess B nicht mehr durch den Semaphor "geschützt" wenn/falls Prozess C kommt vorbei. Außerdem ist die Manpage bestenfalls verwirrend:

"Der Semaphorname wird sofort entfernt. Der Semaphor wird zerstört, sobald alle anderen Prozesse, die den Semaphor geöffnet haben, ihn schließen."

Wie kann es das Objekt sofort zerstören, wenn es auf andere Prozesse warten muss, um den Semaphor zu schließen?

Klar verstehe ich nicht die ordnungsgemäße Verwendung von Semaphor-Objekten unter Linux. Danke für jede Hilfe. Im Folgenden finden Sie einen Beispielcode, den ich zum Testen verwende.

int main(void) 
{ 
    sem_t *pSemaphore = sem_open("/MyName", O_CREAT, S_IRUSR | S_IWUSR, 1); 
    if(pSemaphore != SEM_FAILED) 
    { 
     if(sem_wait(pSemaphore) == 0) 
     { 
      // Perform "protected" operations here 

      sem_post(pSemaphore); 
     } 

     sem_close(pSemaphore); 
     sem_unlink("/MyName"); 
    } 

    return 0; 
} 
+1

Ich denke, Sie lesen die Handbuchseite falsch. "Der Name des Semaphors wird sofort entfernt" bedeutet wörtlich, was er sagt - der Name wird entfernt, so dass keine weiteren Prozesse auf den Semaphor mit diesem Namen zugreifen können. Dies bedeutet nicht, dass der Semaphor entfernt wird, nur der Name.Der zweite Satz beschreibt, wenn der Semaphor entfernt wird - nachdem jeder Prozess, der ihn gerade geöffnet hat, ihn geschlossen hat – twalberg

+0

Also ich denke, die Frage wird, an welchem ​​Punkt nennst du sem_unlink(), um einen Semaphor zu entfernen? Es scheint der einzige Weg, um sicherzustellen, dass dies korrekt funktioniert, ist, den Semaphor auf unbestimmte Zeit auf dem System zu belassen. Das klingt nach schlampiger Programmierung, aber ich sehe keine andere Lösung. – user2124642

+1

Ich denke, die Idee ist, dass Sie es an jedem Punkt entfernen Sie entscheiden, dass Sie nicht mehr wollen, dass neue Prozesse an es anhängen können. Das System lässt Prozesse, die bereits angehängt sind, weiterarbeiten, nur Müll sammelt die Ressourcen, wenn der letzte gerade aktive Benutzer weggeht. Ich werde nicht beurteilen, ob das "schlampig" ist oder nicht, aber denken Sie daran, dies ist eine ziemlich alte Schnittstelle/API, also ist es vielleicht nicht "ideal" nach heutigen Standards, aber es funktioniert immer noch für das, was es war entwickelt für und ist somit weiterhin nützlich. – twalberg

Antwort

7

Antwort auf Ihre Fragen:

  1. Im Vergleich zum Semaphore Verhalten für Fenster, die Sie beschreiben , POSIX Semaphore sind Kernel persistent. Das bedeutet, dass der Semaphor seinen Wert behält, auch wenn kein Prozess den Semaphor geöffnet hat. (Die Referenzzählung der Semaphore wäre 0)

  2. Wenn Prozess A sem_unlink() aufruft, während Prozess B das Semaphor gesperrt hat. Dies bedeutet, dass der Referenzzähler der Semaphore nicht 0 ist und nicht zerstört wird.

Grundfunktionen von sem_close vs sem_unlink, ich denke, allgemeines Verständnis helfen:

sem_close: die Nähe ist ein Semaphore, dies auch getan, wenn ein Prozess beendet wird. Der Semaphor verbleibt immer noch im System.

sem_unlink: werden nur dann aus dem System entfernt, wenn der Referenzzähler den Wert 0 erreicht (dh nach allen Prozessen, in denen er geöffnet ist, rufen Sie sem_close auf oder werden beendet).

Referenzen: Buch - Unix Networking Programming-übergreifenden Kommunikation von W.Richard Stevens, Band 2, CH10

+0

ist es möglich Semaphor 'sem_open' in einem anderen Prozess seit 'sem_unlink' (aber 'sem_close' wird nicht aufgerufen) für diesen Namen aufgerufen wird, oder es wird neues Kernel-Objekt erstellen? – SBKarr

+0

@SBKarr es erstellt ein neues Kernel-Objekt. –

3

Die sem_unlink() Funktion der Semaphore mit Namen und Marken die Semaphore werden, sobald alle identifiziert entfernt zerstört Prozesse hören auf, es zu verwenden (das kann sofort bedeuten, wenn alle Prozesse, die den geöffneten Semaphor hatten, es bereits geschlossen haben).

+0

Gut, ich habe mich darüber gewundert. Die Manpage gibt nicht explizit an, was passiert, wenn ein Semaphor beim Aufruf von sem_unlink bereits vollständig geschlossen ist. Interessanterweise bedeutet dies, dass der Aufräum-Thread entweder sem_close, dann sem_unlink oder sem_unlink und dann sem_close ausführen kann. – Urhixidur