shmget(2) System Calls Manual shmget(2) NAZWA shmget - tworzy segment pamieci dzielonej Systemu V BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include int shmget(key_t key, size_t size, int shmflg); OPIS shmget() zwraca identyfikator segmentu pamieci dzielonej Systemu V, skojarzonego z wartoscia (kluczem) przekazana w parametrze key. Moze sluzyc albo do pozyskania identyfikatora uprzednio utworzonego segmentu pamieci dzielonej (gdy shmflg wynosi zero i key nie ma wartosci IPC_PRIVATE) lub do utworzenia nowego. Nowy segment, o rozmiarze rownym wartosci parametru size zaokraglonym w gore do wielokrotnosci PAGE_SIZE, zostanie utworzony, jesli parametr key bedzie miec wartosc IPC_PRIVATE lub jesli bedzie miec inna wartosc oraz segment skojarzony z key nie istnieje, a w parametrze shmflg zostanie przekazany znacznik IPC_CREAT. Jezeli w parametrze shmflg podano zarowno IPC_CREAT, jak i IPC_EXCL oraz juz istnieje segment w pamieci dzielonej o kluczu key, to shmget() konczy sie bledem, ustawiajac errno na wartosc EEXIST. (Dziala to analogicznie do O_CREAT | O_EXCL w open(2)). Wartosc shmflg sklada sie z: IPC_CREAT Tworzy nowy segment. Jesli ten znacznik nie zostanie ustawiony, to shmget() sprobuje znalezc segment skojarzony z key i sprawdzic, czy uzytkownik ma uprawnienia dostepu do segmentu. IPC_EXCL Ta flaga przekazana lacznie z IPC_CREAT zapewnia, ze to wywolanie utworzy segment. Jesli segment juz istnieje, wywolanie zawiedzie. SHM_HUGETLB (od Linuksa 2.6) Dolacza segment uzywajac duzych (,,huge") stron. Dalsze informacje mozna znalezc w pliku Documentation/admin-guide/mm/hugetlbpage.rst w zrodlach jadra Linux. SHM_HUGE_2MB SHM_HUGE_1GB (od Linuksa 3.8) Uzywany w polaczeniu z SHM_HUGETLB do wybrania alternatywnych rozmiarow stron hugetlb (odpowiednio, 2 MB i 1 GB) w systemach obslugujacych wiele rozmiarow stron hugetlb. Ogolniej, pozadany rozmiar duzej strony mozna skonfigurowac kodujac go w szesciu bajtach na przesunieciu SHM_HUGE_SHIFT za pomoca logarytmu o podstawie 2. Dlatego, powyzsze dwie stale sa zdefiniowane jako: #define SHM_HUGE_2MB (21 << SHM_HUGE_SHIFT) #define SHM_HUGE_1GB (30 << SHM_HUGE_SHIFT) Dodatkowe informacje mozna odnalezc przy omowieniu podobnie nazwanych stalych w mmap(2). SHM_NORESERVE (od Linuksa 2.6.15) Ten znacznik stosuje sie w takim samym celu jak znacznik MAP_NORESERVE funkcji mmap(2). Nie rezerwuje przestrzeni wymiany dla tego segmentu. Jesli przestrzen wymiany zostanie zarezerwowana, ma sie gwarancje, ze jest mozliwe zmodyfikowanie segmentu. Gdy przestrzen wymiany nie jest zarezerwowana, mozna otrzymac sygnal SIGSEGV podczas proby zapisu do segmentu, gdy zabraknie dostepnej fizycznej pamieci. Patrz takze opis pliku /proc/sys/vm/overcommit_memory w proc(5). Oprocz powyzszych flag, 9 najmniej znaczacych bitow sgmflg okresla prawa dostepu do segmentu dla jego wlasciciela, grupy oraz innych. Bity sa w takim samym formacie i maja takie samo znaczenie, jak parametr mode wywolania open(2). Prawa uruchamiania nie sa obecnie uzywane przez system. Jezeli tworzona jest nowa kolejka komunikatow, wywolanie to w nastepujacy sposob inicjuje strukture danych msqid_ds (patrz msgctl(2)): o shm_perm.cuid i shm_perm.uid przyjmuja wartosc efektywnego identyfikatora wlasciciela procesu wywolujacego. o shm_perm.cgid i shm_perm.gid przyjmuja wartosc efektywnego identyfikatora grupy procesu wywolujacego. o 9 najmniej znaczacych bitow pola shm_perm.mode jest kopiowanych z 9 najmniej znaczacych bitow shmflg. o shm_segsz jest ustawiane na wartosc parametru size. o shm_lpid, shm_nattch, shm_atime i shm_dtime sa ustawiane na 0. o shm_ctime jest ustawiane na biezacy czas. Jesli dany segment pamieci dzielonej juz istnieje, to sa weryfikowane uprawnienia i jest sprawdzane, czy segment nie jest przeznaczony do usuniecia. WARTOSC ZWRACANA W przypadku powodzenia zwracany jest poprawny identyfikator pamieci wspoldzielonej. W razie wystapienia bledu zwracane jest -1 i ustawiana jest errno wskazujac blad. BLEDY EACCES Uzytkownik nie ma praw dostepu do zadanego segmentu pamieci dzielonej oraz nie ma przywileju CAP_IPC_OWNER (ang. capability) w przestrzeni nazw uzytkownika, ktora zarzadza jego przestrzenia nazw IPC. EEXIST IPC_CREAT i IPC_EXCL byly okreslone w shmflg, lecz segment pamieci dzielonej juz istnieje dla key. EINVAL Mial byc utworzony nowy segment, a wartosc size jest mniejsza niz SHMMIN lub wieksza niz SHMMAX. EINVAL Segment dla podanego key istnieje, lecz size jest wiekszy niz rozmiar tego segmentu. ENFILE Zostalo osiagniete systemowe ograniczenie na calkowita liczbe otwartych plikow. ENOENT Segment o zadanej wartosci key nie istnieje i nie ustawiono znacznika IPC_CREAT. ENOMEM Nie udalo sie przydzielic pamieci dla segmentu. ENOSPC Wszystkie mozliwe identyfikatory pamieci dzielonej zostaly wykorzystane (SHMMNI) lub przydzielenie segmentu o zadanym rozmiarze size spowodowaloby przekroczenie systemowego ograniczenia na wielkosc pamieci dzielonej (SHMALL). EPERM Podano znacznik SHM_HUGETLB, ale proces wywolujacy nie byl uprzywilejowany (nie mial przywileju CAP_IPC_LOCK) oraz nie jest czlonkiem grupy sysctl_hugetlb_shm_group; zob. opis /proc/sys/vm/sysctl_hugetlb_shm_group w podreczniku proc(5). STANDARDY POSIX.1-2008. SHM_HUGETLB i SHM_NORESERVE sa linuksowymi rozszerzeniami. HISTORIA POSIX.1-2001, SVr4. 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 shmflg i utworzy nowy segment pamieci dzielonej. Limity pamieci dzielonej Nastepujace ograniczenia odnoszace sie do zasobow pamieci dzielonej dotycza wywolania shmget(): SHMALL Systemowy limit calkowitej wielkosci pamieci dzielonej, mierzony w jednostkach systemowego rozmiaru strony. W Linuksie to ograniczenie mozna odczytac i zmienic, uzywajac pliku /proc/sys/kernel/shmall. Od Linuksa 3.16 domyslna wartoscia tego limitu jest: ULONG_MAX - 2^24 Ta wartosc (odpowiednia dla systemow 32 i 64-bitowych) skutkuje brakiem limitow dla alokacji. Ta wartosc, zamiast ULONG_MAX, zostala wybrana jako domyslna, aby zapobiec przypadkom gdy pewne stare aplikacje zwiekszaly istniejacy limit bez sprawdzania jego wartosci biezacej. Moglo to doprowadzic do przepelnienia wartosci, jesli limit byl ustawiony na ULONG_MAX. Od Linuksa 2.4 do 3.15 domyslna wartoscia limitu bylo: SHMMAX / PAGE_SIZE * (SHMMNI / 16) Jesli nie zmodyfikowano SHMMAX i SHMMNI, to przemnozenie wyniku tego dzialania przez rozmiar strony (aby otrzymac wartosc w bajtach) dawalo wartosc 8 GB jako limit calkowitej pamieci uzywanej przez wszystkie segmenty pamieci dzielonej. SHMMAX Maksymalny rozmiar segmentu pamieci dzielonej w bajtach. W Linuksie to ograniczenie mozna odczytac i zmienic, uzywajac pliku /proc/sys/kernel/shmmax. Od Linuksa 3.16 domyslna wartoscia tego limitu jest: ULONG_MAX - 2^24 Ta wartosc (odpowiednia dla systemow 32 i 64-bitowych) skutkuje brakiem limitow dla alokacji. Wyjasnienie dlaczego jest to wartosc domyslna (zamiast ULONG_MAX) znajduje sie w opisie SHMALL. Od Linuksa 2.2 do 3.15 domyslna wartoscia tego limitu bylo 0x2000000 (32 MB). Poniewaz nie da sie przypisac jedynie fragmentu segmentu pamieci dzielonej, wartosc pamieci wirtualnej naklada kolejne ograniczenie na maksymalny rozmiar uzytecznego segmentu np. na architekturze i386 najwiekszy segment ktory mozna zmapowac ma rozmiar okolo 2,8 GB, a na x86_64 limit ten wynosi okolo 127 TB. SHMMIN Minimalny rozmiar (w bajtach) pojedynczego segmentu pamieci dzielonej: zalezny od implementacji (obecnie 1 bajt, ale efektywny minimalny rozmiar wynosi PAGE_SIZE). SHMMNI Systemowy limit liczby segmentow pamieci dzielonej. W Linuksie 2.2 domyslna wartosc tego limitu wynosila 128; od Linuksa 2.4 domyslna wartosc wynosi 4096. W Linuksie to ograniczenie mozna odczytac i zmienic, uzywajac pliku /proc/sys/kernel/shmmni. System Linux nie stawia ograniczen dotyczacych liczby segmentow pamieci dzielonej dolaczonych do jednego procesu (SHMSEG). Uwagi linuksowe Do Linuksa 2.3.30 Linux zwracal EIDRM dla shmget() na segmencie pamieci dzielonej przeznaczonym do usuniecia. USTERKI Nazwa IPC_PRIVATE prawdopodobnie nie jest najszczesliwsza. IPC_NEW w sposob bardziej przejrzysty odzwierciedlaloby role tej wartosci. PRZYKLADY Zobacz shmop(2). ZOBACZ TAKZE memfd_create(2), shmat(2), shmctl(2), shmdt(2), ftok(3), capabilities(7), shm_overview(7), sysvipc(7) TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: 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.12 23 lipca 2024 r. shmget(2)