Provided by: manpages-pl-dev_4.28.0-2_all 

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
Tłumaczenie niniejszej strony podręcznika: 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 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.
Linux man-pages 6.9.1 15 czerwca 2024 r. semget(2)