oracular (2) semget.2.gz

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⟩.