Provided by: manpages-pl-dev_4.23.1-1_all bug

NAZWA

       semget - pobiera identyfikator zestawu semaforów Systemu V

BIBLIOTEKA

       Standardowa biblioteka C (libc, -lc)

SKŁADNIA

       #include <sys/sem.h>

       int semget(key_t key, int nsems, int semflg);

OPIS

       Wywołanie systemowe semget() zwraca identyfikator zestawu semaforów Systemu V skojarzonego
       z parametrem key. Może służyć albo  do  pozyskania  identyfikatora  uprzednio  utworzonego
       zestawu  semaforów  (gdy  semflg  wynosi  zero,  a key nie ma wartości IPC_PRIVATE) lub do
       utworzenia nowego zestawu.

       Nowy zestaw składający się z nsems  semaforów   zostanie  utworzony,  jeśli  parametr  key
       będzie  mieć wartość IPC_PRIVATE lub gdy zestaw semaforów skojarzony z key nie istnieje, a
       w parametrze semflg zostanie przekazany znacznik IPC_CREAT.

       Jeśli w parametrze semflg podano zarówno IPC_CREAT,  jak  i  IPC_EXCL  oraz  już  istnieje
       zestaw  semaforów o kluczu key, to semget() kończy się błędem, ustawiając errno na wartość
       EEXIST (działa to analogicznie do O_CREAT | O_EXCL w open(2)).

       Podczas tworzenia, 9 najmniej znaczących bitów argumentu semflg określa prawa  dostępu  do
       zestawu  semaforów (dla właściciela, grupy i innych).  Bity te mają ten sam format i takie
       samo znaczenie, jak parametr mode wywołania open(2) (prawa uruchamiania nie są istotne dla
       semaforów, natomiast prawa zapisu oznaczają możliwość zmiany wartości semaforów).

       Podczas  tworzenia  nowego  zestawu  semaforów  semget()  inicjuje   związaną  z  zestawem
       semaforów strukturę semid_ds (patrz semctl(2)) w następujący sposób:

       •  sem_perm.cuid i sem_perm.uid przyjmują wartość efektywnego  identyfikatora  właściciela
          procesu wywołującego.

       •  sem_perm.cgid i sem_perm.gid przyjmują wartość efektywnego identyfikatora grupy procesu
          wywołującego.

       •  9 najmniej znaczących bitów pola sem_perm.mode jest kopiowanych z 9 najmniej znaczących
          bitów semflg.

       •  sem_nsems jest ustawiane na wartość nsems.

       •  sem_otime przyjmie wartość 0.

       •  sem_ctime przypisywany jest bieżący czas.

       Parametr  nsems  może mieć wartość 0 (nie jest brany pod uwagę), jeśli nie będzie tworzony
       zestaw semaforów. W przeciwnym przypadku parametr nsems musi być większy od 0  i  mniejszy
       lub równy maksymalnej liczbie semaforów w zestawie (SEMMSL).

       Jeżeli zestaw semaforów już istnieje, to weryfikowane są uprawnienia.

WARTOŚĆ ZWRACANA

       W   przypadku   powodzenia,   semget()  zwraca  identyfikator  zestawu  semaforów  (liczbę
       nieujemną). W razie wystąpienia błędu zwracane jest -1 i ustawiane errno wskazując błąd.

BŁĘDY

       EACCES Zestaw semaforów identyfikowany kluczem key istnieje, ale proces wywołujący ani nie
              ma  praw  dostępu  do  niego,  ani  nie  ma  ustawionego przywileju CAP_IPC_OWNER w
              przestrzeni nazw użytkownika, która zarządza jego przestrzenią nazw IPC.

       EEXIST IPC_CREAT i IPC_EXCL  określono  w  semflg,  lecz  zestaw  semaforów  dla  key  już
              istnieje.

       EINVAL nsems  jest mniejsze niż 0 lub większe niż ograniczenie liczby semaforów w zestawie
              (SEMMSL)

       EINVAL Zestaw semaforów, do którego odnosi się key już istnieje, lecz nsems  jest  większe
              niż liczba semaforów w tym zestawie.

       ENOENT Nie  ma  zestawu  semaforów  o  identyfikatorze key i znacznik IPC_CREAT nie został
              przekazany w parametrze semflg.

       ENOMEM Zestaw semaforów powinien zostać utworzony, ale w systemie  brak  jest  pamięci  na
              utworzenie nowej struktury danych.

       ENOSPC Nastąpiła  próba  przekroczenia  ograniczenia  liczby zestawów (SEMMNI) lub łącznej
              liczby semaforów w systemie (SEMMNS).

STANDARDY

       POSIX.1-2008.

HISTORIA

       SVr4, POSIX.1-2001.

UWAGI

       IPC_PRIVATE nie jest znacznikiem, ale szczególną wartością typu key_t.  Jeśli  wartość  ta
       zostanie  użyta  jako  parametr  key,  to  system  uwzględni  jedynie  9 najniższych bitów
       parametru msgflg i (w razie powodzenia) utworzy nowy zestaw semaforów.

   Inicjowanie semaforów
       Wartości semaforów w nowo utworzonym zestawie są nieokreślone (POSIX.1-2001  jasno  o  tym
       mówi,   choć  POSIX.1-2008  określa,  że  przyszła  wersja  tego  standardu  może  wymagać
       implementacji inicjującej semafory z wartością 0). Mimo że Linux, tak jak i  wiele  innych
       implementacji,  nadaje  im  wartość początkową równą 0, to przenośne aplikacje nie powinny
       zależeć od tego zachowania i zamiast tego powinny  wyraźnie  inicjować  semafory  żądanymi
       wartościami.

       Aby  zainicjować  semafory,  należy  na zestawie semaforów użyć operacji SETVAL lub SETALL
       wywołania semctl(2). W sytuacji gdy wiele procesów  nie  wie,  który  pierwszy  zainicjuje
       zestaw  semaforów,  to  aby  uniknąć sytuacji wyścigu, można sprawdzić, czy pole sem_otime
       powiązanej struktury danych zwracanej  przez  operację  IPC_STAT  wywołania  semctl(2)  ma
       wartość niezerową.

   Limity semaforów
       Wywołania  semget()  dotyczą  następujące  ograniczenia  zasobów  związanych  z  zestawami
       semaforów:

       SEMMNI Limit liczby zestawów semaforów w systemie. Przed Linuksem 3.19,  domyślna  wartość
              tego  limitu  wynosiła  128.  Od  Linuksa  3.19  jest  to  32 000.  Pod Linuksem to
              ograniczenie  można   odczytać   i   zmienić,   używając   czwartego   pola   pliku
              /proc/sys/kernel/sem).

       SEMMSL Maksymalna  liczba  semaforów dla danego ID semafora. Przed Linuksem 3.19, domyślna
              wartość tego limitu wynosiła 250. Od Linuksa 3.19 jest to 32 000. Pod  Linuksem  to
              ograniczenie   można   odczytać   i   zmienić,   używając   pierwszego  pola  pliku
              /proc/sys/kernel/sem).

       SEMMNS Limit liczby semaforów w systemie:  wartość  zależna  od  lokalnych  ustawień  (pod
              Linuksem  to  ograniczenie  można  odczytać i zmienić, używając drugiego pola pliku
              /proc/sys/kernel/sem). Proszę zauważyć, że systemowa liczba semaforów jest  również
              ograniczona przez iloczyn SEMMSL i SEMMNI.

USTERKI

       Nazwa  IPC_PRIVATE  prawdopodobnie  nie  jest  najszczęśliwsza.  IPC_NEW w sposób bardziej
       przejrzysty odzwierciedlałoby rolę tej wartości.

PRZYKŁADY

       Program  pokazany  niżej  używa  semget()  do  utworzenia  nowego  zestawu  semaforów  lub
       pozyskania  identyfikatora zestawu istniejącego. Tworzy key do semget() za pomocą ftok(3).
       Pierwsze dwa argumenty wiersza poleceń są używane jako argumenty  pathname  i  proj_id  do
       ftok(3).  Trzeci  argument  wiersza  poleceń  jest  liczbą,  określającą argument nsems do
       semget(). Opcje wiersza poleceń mogą posłużyć do określenia znaczników  IPC_CREAT  (-c)  i
       IPC_EXCL (-x) do wywołania semget(). Użycie programu pokazano poniżej.

       Najpierw  tworzone  są dwa pliki, które posłużą do wygenerowania kluczy za pomocą ftok(3),
       utworzenia dwóch zestawów semaforów za pomocą tych plików, a następnie wypisania  zestawów
       używając ipcs(1):

           $ touch mójklucz mójklucz2
           $ ./t_semget -c mójklucz p 1
           ID = 9
           $ ./t_semget -c mójklucz2 p 2
           ID = 10
           $ ipcs -s

           ------ Semaphore Arrays --------
           key        semid      owner      perms      nsems
           0x7004136d 9          mtk        600        1
           0x70041368 10         mtk        600        2

       Następnie  demonstrujemy fakt, że gdy semctl(2) otrzymuje taki sam key (wygenerowany przez
       takie same argumenty do ftok(3)), zwraca identyfikator już istniejącego zestawu semaforów:

           $ ./t_semget -c mójklucz p 1
           ID = 9

       Na końcu, demonstrujemy rodzaj kolizji, jaka może wystąpić gdy przekaże się ftok(3)  różne
       argumenty pathname, które mają ten sam numer i-węzła.

           $ ln mójklucz link
           $ ls -i1 link mójklucz
           2233197 link
           2233197 mójklucz
           $ ./t_semget link p 1       # Generuje taki sam klucz, jak 'mójklucz'
           ID = 9

   Kod źródłowy programu

       /* t_semget.c

          Na licencji GNU General Public License v2 lub późniejszej.
       */
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/ipc.h>
       #include <sys/sem.h>
       #include <unistd.h>

       static void
       usage(const char *pname)
       {
           fprintf(stderr, "Użycie: %s [-cx] ścieżka id-proj l-sem\n",
                   pname);
           fprintf(stderr, "    -c        Używa znacznika IPC_CREAT\n");
           fprintf(stderr, "    -x        Używa znacznika IPC_EXCL\n");
           exit(EXIT_FAILURE);
       }

       int
       main(int argc, char *argv[])
       {
           int    semid, nsems, flags, opt;
           key_t  key;

           flags = 0;
           while ((opt = getopt(argc, argv, "cx")) != -1) {
               switch (opt) {
               case 'c': flags |= IPC_CREAT;   break;
               case 'x': flags |= IPC_EXCL;    break;
               default:  usage(argv[0]);
               }
           }

           if (argc != optind + 3)
               usage(argv[0]);

           key = ftok(argv[optind], argv[optind + 1][0]);
           if (key == -1) {
               perror("ftok");
               exit(EXIT_FAILURE);
           }

           nsems = atoi(argv[optind + 2]);

           semid = semget(key, nsems, flags | 0600);
           if (semid == -1) {
               perror("semget");
               exit(EXIT_FAILURE);
           }

           printf("ID = %d\n", semid);

           exit(EXIT_SUCCESS);
       }

ZOBACZ TAKŻE

       semctl(2), semop(2), ftok(3), capabilities(7), sem_overview(7), sysvipc(7)

TŁUMACZENIE

       Autorami   polskiego   tłumaczenia   niniejszej   strony  podręcznika  są:  Rafał  Lewczuk
       <R.Lewczuk@elka.pw.edu.p>,  Andrzej  Krzysztofowicz   <ankry@green.mf.pg.gda.pl>,   Robert
       Luberda <robert@debian.org> i Michał Kułach <michal.kulach@gmail.com>

       Niniejsze  tłumaczenie  jest  wolną  dokumentacją. Bliższe informacje o warunkach licencji
       można   uzyskać   zapoznając   się   z   GNU   General   Public   License   w   wersji   3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   lub   nowszej.   Nie  przyjmuje  się  ŻADNEJ
       ODPOWIEDZIALNOŚCI.

       Błędy w tłumaczeniu  strony  podręcznika  prosimy  zgłaszać  na  adres  listy  dyskusyjnej
       ⟨manpages-pl-list@lists.sourceforge.net⟩.