2013-03-01 9 views
11

Jestem trochę zdezorientowany przez Linux API sem_unlink(), głównie kiedy i dlaczego go wywołać. Używałem semaforów w Windows od wielu lat. W systemie Windows po zamknięciu ostatniego uchwytu nazwanego semafora system usuwa bazowy obiekt jądra. Ale pojawia się w Linuksie ty, programista, musisz usunąć obiekt jądra, wywołując sem_unlink(). Jeśli nie, obiekt jądra działa w folderze/dev/shm.Kiedy wywołać sem_unlink()?

Problem, który napotykam, jeśli proces A wywoła sem_unlink(), podczas gdy proces B ma semafor zablokowany, natychmiast niszczy semafor, a teraz proces B nie jest już "chroniony" przez semafor, gdy/jeśli proces C przychodzi. Co więcej, strona man jest w najlepszym razie myląca:

"Nazwa semafora jest natychmiast usuwana, semafor jest niszczony, gdy wszystkie inne procesy, które mają semafor, otwierają go."

W jaki sposób może on natychmiast zniszczyć obiekt, jeśli musi czekać na zamknięcie semafora w innych procesach?

Najwyraźniej nie rozumiem właściwego wykorzystania obiektów semaforów w systemie Linux. Dzięki za pomoc. Poniżej znajduje się przykładowy kod, którego używam do testowania tego.

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

Myślę, że źle czytasz stronę podręcznika. "Nazwa semafora jest natychmiast usuwana" oznacza dosłownie to, co mówi - nazwa jest usuwana, aby żadne dalsze procesy nie miały dostępu do semafora o tej nazwie. Nie oznacza to, że semafor zostanie usunięty, tylko nazwa.Drugie zdanie opisuje, kiedy semafor został usunięty - po każdym procesie, który obecnie go otworzył, zamknął go. – twalberg

+0

Tak więc domyślam się, że pojawia się pytanie, w którym momencie wywołasz sem_unlink() w celu usunięcia semafora? Wydaje się, że jedynym sposobem zapewnienia, że ​​działa to poprawnie, jest pozostawienie semafora w nieskończoność w systemie. To wygląda na niechlujne programowanie, ale nie widzę innego rozwiązania. – user2124642

+1

Myślę, że pomysł polega na usunięciu go w dowolnym momencie, w którym zdecydujesz, że nie chcesz, aby nowe procesy mogły się do niego przyczepić. System zezwala na procesy, które są już dołączone, aby kontynuować działanie, a jedynie śmieci zbierają zasoby, gdy ostatni aktywny użytkownik zniknie. Nie oceniam, czy jest to "niechlujne", czy nie, ale należy pamiętać, że jest to raczej stary interfejs/interfejs API, więc może nie być "idealny" według dzisiejszych standardów, ale nadal działa na to, co było Przeznaczony dla, i dlatego nadal jest przydatny. – twalberg

Odpowiedz

7

odpowiedzi na pytania:

  1. W porównaniu do semafora zachowanie dla okien opisujesz, semafory POSIX są jądra trwałe. Oznacza to, że semafor zachowuje jego wartość, nawet jeśli żaden proces nie ma otwartego semafora . (liczba odwołań semafora wynosiłaby 0)

  2. Jeśli proces A wywoła sem_unlink(), podczas gdy proces B ma semafor zablokowany. Oznacza to, że liczba odwołań semafora nie wynosi 0 i nie zostanie zniszczona.

Podstawowe działanie sem_close vs sem_unlink, myślę, że pomoże ogólnego zrozumienia:

sem_close: blisko znajduje się semafor, to także zrobić, kiedy wyjść procesowych. semafor wciąż pozostaje w systemie.

sem_unlink: zostanie usunięty z systemu tylko wtedy, gdy licznik osiągnie wartość 0 odniesienia (to jest po wszystkich procesach, które jest otwarte, połączenia sem_close lub jest zakończony).

Referencje: Book - Unix sieci Programming-Interprocess Komunikacja przez W.Richard Stevens, tom 2, CH10

+0

możliwe jest semafor 'sem_open' w innym procesie od' sem_unlink' (ale 'sem_close' nie jest wywoływana) dla tej nazwy jest wywoływana, lub utworzy nowy obiekt jądra? – SBKarr

+0

@SBKarr tworzy nowy obiekt jądra. –

3

Funkcja sem_unlink() usuwa semafor identyfikowany przez nazwę i znaków semafora zostać zniszczone raz wszystko procesy przestają z niego korzystać (może to oznaczać, że wszystkie procesy z otwartym semaforem już je zamknęły).

+0

Dobrze, zastanawiałem się nad tym. Strona man nie określa wprost, co się stanie, jeśli semafor jest już dokładnie zamknięty po wywołaniu sem_unlink. Co ciekawe, oznacza to, że wątek czyszczący może wykonać albo sem_close, potem sem_unlink, albo sem_unlink, a następnie sem_close. – Urhixidur

Powiązane problemy