semget(2) System Calls Manual semget(2) NAZWA semget - pobiera identyfikator zestawu semaforow Systemu V BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include int semget(key_t key, int nsems, int semflg); OPIS Wywolanie systemowe semget() zwraca identyfikator zestawu semaforow Systemu V skojarzonego z parametrem key. Moze sluzyc albo do pozyskania identyfikatora uprzednio utworzonego zestawu semaforow (gdy semflg wynosi zero, a key nie ma wartosci IPC_PRIVATE) lub do utworzenia nowego zestawu. Nowy zestaw skladajacy sie z nsems semaforow zostanie utworzony, jesli parametr key bedzie miec wartosc IPC_PRIVATE lub gdy zestaw semaforow skojarzony z key nie istnieje, a w parametrze semflg zostanie przekazany znacznik IPC_CREAT. Jesli w parametrze semflg podano zarowno IPC_CREAT, jak i IPC_EXCL oraz juz istnieje zestaw semaforow o kluczu key, to semget() konczy sie bledem, ustawiajac errno na wartosc EEXIST (dziala to analogicznie do O_CREAT | O_EXCL w open(2)). Podczas tworzenia, 9 najmniej znaczacych bitow argumentu semflg okresla prawa dostepu do zestawu semaforow (dla wlasciciela, grupy i innych). Bity te maja ten sam format i takie samo znaczenie, jak parametr mode wywolania open(2) (prawa uruchamiania nie sa istotne dla semaforow, natomiast prawa zapisu oznaczaja mozliwosc zmiany wartosci semaforow). Podczas tworzenia nowego zestawu semaforow semget() inicjuje zwiazana z zestawem semaforow strukture semid_ds (patrz semctl(2)) w nastepujacy sposob: o sem_perm.cuid i sem_perm.uid przyjmuja wartosc efektywnego identyfikatora wlasciciela procesu wywolujacego. o sem_perm.cgid i sem_perm.gid przyjmuja wartosc efektywnego identyfikatora grupy procesu wywolujacego. o 9 najmniej znaczacych bitow pola sem_perm.mode jest kopiowanych z 9 najmniej znaczacych bitow semflg. o sem_nsems jest ustawiane na wartosc nsems. o sem_otime przyjmie wartosc 0. o sem_ctime przypisywany jest biezacy czas. Parametr nsems moze miec wartosc 0 (nie jest brany pod uwage), jesli nie bedzie tworzony zestaw semaforow. W przeciwnym przypadku parametr nsems musi byc wiekszy od 0 i mniejszy lub rowny maksymalnej liczbie semaforow w zestawie (SEMMSL). Jezeli zestaw semaforow juz istnieje, to weryfikowane sa uprawnienia. WARTOSC ZWRACANA W przypadku powodzenia, semget() zwraca identyfikator zestawu semaforow (liczbe nieujemna). W razie wystapienia bledu zwracane jest -1 i ustawiane errno wskazujac blad. BLEDY EACCES Zestaw semaforow identyfikowany kluczem key istnieje, ale proces wywolujacy ani nie ma praw dostepu do niego, ani nie ma ustawionego przywileju CAP_IPC_OWNER w przestrzeni nazw uzytkownika, ktora zarzadza jego przestrzenia nazw IPC. EEXIST IPC_CREAT i IPC_EXCL okreslono w semflg, lecz zestaw semaforow dla key juz istnieje. EINVAL nsems jest mniejsze niz 0 lub wieksze niz ograniczenie liczby semaforow w zestawie (SEMMSL) EINVAL Zestaw semaforow, do ktorego odnosi sie key juz istnieje, lecz nsems jest wieksze niz liczba semaforow w tym zestawie. ENOENT Nie ma zestawu semaforow o identyfikatorze key i znacznik IPC_CREAT nie zostal przekazany w parametrze semflg. ENOMEM Zestaw semaforow powinien zostac utworzony, ale w systemie brak jest pamieci na utworzenie nowej struktury danych. ENOSPC Nastapila proba przekroczenia ograniczenia liczby zestawow (SEMMNI) lub lacznej liczby semaforow w systemie (SEMMNS). STANDARDY POSIX.1-2024. HISTORIA SVr4, POSIX.1-2001. UWAGI IPC_PRIVATE nie jest znacznikiem, ale szczegolna wartoscia typu key_t. Jesli wartosc ta zostanie uzyta jako parametr key, to system uwzgledni jedynie 9 najnizszych bitow parametru msgflg i (w razie powodzenia) utworzy nowy zestaw semaforow. Inicjowanie semaforow Wartosci semaforow w nowo utworzonym zestawie sa nieokreslone (POSIX.1-2001 jasno o tym mowi, choc POSIX.1-2008 okresla, ze przyszla wersja tego standardu moze wymagac implementacji inicjujacej semafory z wartoscia 0). Mimo ze Linux, tak jak i wiele innych implementacji, nadaje im wartosc poczatkowa rowna 0, to przenosne aplikacje nie powinny zalezec od tego zachowania i zamiast tego powinny wyraznie inicjowac semafory zadanymi wartosciami. Aby zainicjowac semafory, nalezy na zestawie semaforow uzyc operacji SETVAL lub SETALL wywolania semctl(2). W sytuacji gdy wiele procesow nie wie, ktory pierwszy zainicjuje zestaw semaforow, to aby uniknac sytuacji wyscigu, mozna sprawdzic, czy pole sem_otime powiazanej struktury danych zwracanej przez operacje IPC_STAT wywolania semctl(2) ma wartosc niezerowa. Limity semaforow Wywolania semget() dotycza nastepujace ograniczenia zasobow zwiazanych z zestawami semaforow: SEMMNI Limit liczby zestawow semaforow w systemie. Przed Linuksem 3.19, domyslna wartosc tego limitu wynosila 128. Od Linuksa 3.19 jest to 32 000. Pod Linuksem to ograniczenie mozna odczytac i zmienic, uzywajac czwartego pola pliku /proc/sys/kernel/sem). SEMMSL Maksymalna liczba semaforow dla danego ID semafora. Przed Linuksem 3.19, domyslna wartosc tego limitu wynosila 250. Od Linuksa 3.19 jest to 32 000. Pod Linuksem to ograniczenie mozna odczytac i zmienic, uzywajac pierwszego pola pliku /proc/sys/kernel/sem). SEMMNS Limit liczby semaforow w systemie: wartosc zalezna od lokalnych ustawien (pod Linuksem to ograniczenie mozna odczytac i zmienic, uzywajac drugiego pola pliku /proc/sys/kernel/sem). Prosze zauwazyc, ze systemowa liczba semaforow jest rowniez ograniczona przez iloczyn SEMMSL i SEMMNI. USTERKI Nazwa IPC_PRIVATE prawdopodobnie nie jest najszczesliwsza. IPC_NEW w sposob bardziej przejrzysty odzwierciedlaloby role tej wartosci. PRZYKLADY Program pokazany nizej uzywa semget() do utworzenia nowego zestawu semaforow lub pozyskania identyfikatora zestawu istniejacego. Tworzy key do semget() za pomoca ftok(3). Pierwsze dwa argumenty wiersza polecen sa uzywane jako argumenty pathname i proj_id do ftok(3). Trzeci argument wiersza polecen jest liczba, okreslajaca argument nsems do semget(). Opcje wiersza polecen moga posluzyc do okreslenia znacznikow IPC_CREAT (-c) i IPC_EXCL (-x) do wywolania semget(). Uzycie programu pokazano ponizej. Najpierw tworzone sa dwa pliki, ktore posluza do wygenerowania kluczy za pomoca ftok(3), utworzenia dwoch zestawow semaforow za pomoca tych plikow, a nastepnie wypisania zestawow uzywajac ipcs(1): $ touch mojklucz mojklucz2; $ ./t_semget -c mojklucz p 1; ID = 9 $ ./t_semget -c mojklucz2 p 2; ID = 10 $ ipcs -s; ------ Semaphore Arrays -------- key semid owner perms nsems 0x7004136d 9 mtk 600 1 0x70041368 10 mtk 600 2 Nastepnie demonstrujemy fakt, ze gdy semctl(2) otrzymuje taki sam key (wygenerowany przez takie same argumenty do ftok(3)), zwraca identyfikator juz istniejacego zestawu semaforow: $ ./t_semget -c mojklucz p 1; ID = 9 Na koncu, demonstrujemy rodzaj kolizji, jaka moze wystapic gdy przekaze sie ftok(3) rozne argumenty pathname, ktore maja ten sam numer i-wezla. $ ln mojklucz link; $ ls -i1 link mojklucz; 2233197 link 2233197 mojklucz $ ./t_semget link p 1; # Generuje taki sam klucz, jak 'mojklucz' ID = 9 Kod zrodlowy programu /* t_semget.c Na licencji GNU General Public License v2 lub pozniejszej. */ #include #include #include #include #include static void usage(const char *pname) { fprintf(stderr, "Uzycie: %s [-cx] sciezka id-proj l-sem\n", pname); fprintf(stderr, " -c Uzywa znacznika IPC_CREAT\n"); fprintf(stderr, " -x Uzywa 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 TAKZE semctl(2), semop(2), ftok(3), capabilities(7), sem_overview(7), sysvipc(7) TLUMACZENIE Tlumaczenie niniejszej strony podrecznika: Rafal Lewczuk , Andrzej Krzysztofowicz , Robert Luberda i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.18 8 lutego 2026 r. semget(2)