shmget - utworzenie segmentu pamięci dzielonej Systemu V
Standardowa biblioteka C (
libc,
-lc)
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
shmget() returns the identifier of the System V shared memory
segment associated with the value of the argument
key. It may be used
either to obtain the identifier of a previously created shared memory segment
(when
shmflg is zero and
key does not have the value
IPC_PRIVATE), or to create a new set.
A new shared memory segment, with size equal to the value of
size rounded
up to a multiple of
PAGE_SIZE, is created if
key has the value
IPC_PRIVATE or
key isn't
IPC_PRIVATE, no shared memory
segment corresponding to
key exists, and
IPC_CREAT is specified
in
shmflg.
Jeżeli w parametrze
shmflg podano zarówno
IPC_CREAT,
jak i
IPC_EXCL oraz już istnieje segment w pamięci
dzielonej o kluczu
key, to
shmget() kończy się
błędem, ustawiając
errno na wartość
EEXIST. (Działa to analogicznie do
O_CREAT | O_EXCL w
open(2)).
Wartość
shmflg składa się z:
- IPC_CREAT
- Tworzy nowy segment. Jeśli ten znacznik nie zostanie
ustawiony, to shmget() spróbuje znaleźć
segment skojarzony z key i sprawdzić, czy użytkownik
ma uprawnienia dostępu do segmentu.
- IPC_EXCL
- Ta flaga przekazana łącznie z
IPC_CREAT zapewnia, że to wywołanie utworzy segment.
Jeśli segment już istnieje, wywołanie zawiedzie.
-
SHM_HUGETLB (od Linuksa 2.6)
- Allocate the segment using "huge" pages. See the
Linux kernel source file
Documentation/admin-guide/mm/hugetlbpage.rst for further
information.
-
SHM_HUGE_2MB, SHM_HUGE_1GB (od Linuksa
3.8)
- Used in conjunction with SHM_HUGETLB to select
alternative hugetlb page sizes (respectively, 2 MB and 1 GB)
on systems that support multiple hugetlb page sizes.
- Ogólniej, pożądany rozmiar
dużej strony można skonfigurować kodując go w
sześciu bajtach na przesunięciu SHM_HUGE_SHIFT za
pomocą logarytmu o podstawie 2. Dlatego, powyższe dwie
stałe są zdefiniowane jako:
-
#define SHM_HUGE_2MB (21 << SHM_HUGE_SHIFT)
#define SHM_HUGE_1GB (30 << SHM_HUGE_SHIFT)
- Dodatkowe informacje można odnaleźć
przy omówieniu podobnie nazwanych stałych w
mmap(2).
-
SHM_NORESERVE (od Linuksa 2.6.15)
- Ten znacznik stosuje się w takim samym celu jak
znacznik MAP_NORESERVE funkcji mmap(2). Nie rezerwuje
przestrzeni wymiany dla tego segmentu. Jeśli przestrzeń
wymiany zostanie zarezerwowana, ma się gwarancję, że
jest możliwe zmodyfikowanie segmentu. Gdy przestrzeń wymiany
nie jest zarezerwowana, można otrzymać sygnał
SIGSEGV podczas próby zapisu do segmentu, gdy zabraknie
dostępnej fizycznej pamięci. Patrz także opis pliku
/proc/sys/vm/overcommit_memory w proc(5).
Oprócz powyższych flag, 9 najmniej znaczących bitów
sgmflg określa prawa dostępu do segmentu dla jego
właściciela, grupy oraz innych. Bity są w takim samym
formacie i mają takie samo znaczenie, jak parametr
mode
wywołania
open(2). Prawa uruchamiania nie są obecnie
używane przez system.
Jeżeli tworzona jest nowa kolejka komunikatów, wywołanie to
w następujący sposób inicjuje strukturę danych
msqid_ds (patrz
msgctl(2)):
- •
-
shm_perm.cuid i shm_perm.uid przyjmują
wartość efektywnego identyfikatora właściciela
procesu wywołującego.
- •
-
shm_perm.cgid i shm_perm.gid przyjmują
wartość efektywnego identyfikatora grupy procesu
wywołującego.
- •
- 9 najmniej znaczących bitów pola
shm_perm.mode jest kopiowanych z 9 najmniej znaczących
bitów shmflg.
- •
-
shm_segsz jest ustawiane na wartość
parametru size.
- •
-
shm_lpid, shm_nattch, shm_atime i
shm_dtime są ustawiane na 0.
- •
-
shm_ctime jest ustawiane na bieżący
czas.
Jeśli dany segment pamięci dzielonej już istnieje, to
są weryfikowane uprawnienia i jest sprawdzane, czy segment nie jest
przeznaczony do usunięcia.
W przypadku powodzenia zwracany jest poprawny identyfikator pamięci
współdzielonej. W razie wystąpienia błędu
zwracane jest -1 i ustawiana jest
errno wskazując
błąd.
- EACCES
- The user does not have permission to access the shared
memory segment, and does not have the CAP_IPC_OWNER capability in
the user namespace that governs its IPC namespace.
- EEXIST
-
IPC_CREAT i IPC_EXCL były
określone w shmflg, lecz segment pamięci dzielonej
już istnieje dla key.
- EINVAL
- Miał być utworzony nowy segment, a
wartość size jest mniejsza niż SHMMIN
lub większa niż SHMMAX.
- EINVAL
- Segment dla podanego key istnieje, lecz size
jest większy niż rozmiar tego segmentu.
- ENFILE
- Zostało osiągnięte systemowe
ograniczenie na całkowitą liczbę otwartych
plików.
- ENOENT
- Segment o zadanej wartości key nie istnieje i
nie ustawiono znacznika IPC_CREAT.
- ENOMEM
- Nie udało się przydzielić
pamięci dla segmentu.
- ENOSPC
- Wszystkie możliwe identyfikatory pamięci
dzielonej zostały wykorzystane ( SHMMNI) lub przydzielenie
segmentu o żądanym rozmiarze size
spowodowałoby przekroczenie systemowego ograniczenia na
wielkość pamięci dzielonej ( SHMALL).
- EPERM
- The SHM_HUGETLB flag was specified, but the caller
was not privileged (did not have the CAP_IPC_LOCK capability) and
is not a member of the sysctl_hugetlb_shm_group group; see the
description of /proc/sys/vm/sysctl_hugetlb_shm_group in
proc(5).
POSIX.1-2001, POSIX.1-2008, SVr4.
SHM_HUGETLB i
SHM_NORESERVE są linuksowymi rozszerzeniami.
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
shmflg i utworzy
nowy segment pamięci dzielonej.
Następujące ograniczenia odnoszące się do
zasobów pamięci dzielonej dotyczą wywołania
shmget():
- SHMALL
- Systemowy limit całkowitej wielkości
pamięci dzielonej, mierzony w jednostkach systemowego rozmiaru
strony.
- W Linuksie to ograniczenie można odczytać i
zmienić, używając pliku
/proc/sys/kernel/shmall. Od Linuksa 3.16
domyślną wartością tego limitu
jest:
-
ULONG_MAX - 2^24
- Ta wartość (odpowiednia dla systemów
32 i 64-bitowych) skutkuje brakiem limitów dla alokacji. Ta
wartość, zamiast ULONG_MAX, została wybrana
jako domyślna, aby zapobiec przypadkom gdy pewne stare aplikacje
zwiększały istniejący limit bez sprawdzania jego
wartości bieżącej. Mogło to doprowadzić
do przepełnienia wartości, jeśli limit był
ustawiony na ULONG_MAX.
- Od Linuksa 2.4 do 3.15 domyślną
wartością limitu było:
-
SHMMAX / PAGE_SIZE * (SHMMNI / 16)
- If SHMMAX and SHMMNI were not modified, then
multiplying the result of this formula by the page size (to get a value in
bytes) yielded a value of 8 GB as the limit on the total memory
used by all shared memory segments.
- SHMMAX
- Maksymalny rozmiar segmentu pamięci dzielonej w
bajtach.
- W Linuksie to ograniczenie można odczytać i
zmienić, używając pliku
/proc/sys/kernel/shmmax. Od Linuksa 3.16 domyślną
wartością tego limitu jest:
-
ULONG_MAX - 2^24
- Ta wartość (odpowiednia dla systemów
32 i 64-bitowych) skutkuje brakiem limitów dla alokacji.
Wyjaśnienie dlaczego jest to wartość domyślna
(zamiast ULONG_MAX) znajduje się w opisie
SHMALL.
- From Linux 2.2 up to Linux 3.15, the default value of this
limit was 0x2000000 (32 MiB).
- Because it is not possible to map just part of a shared
memory segment, the amount of virtual memory places another limit on the
maximum size of a usable segment: for example, on i386 the largest
segments that can be mapped have a size of around 2.8 GB, and on
x86-64 the limit is around 127 TB.
- SHMMIN
- Minimalny rozmiar (w bajtach) pojedynczego segmentu
pamięci dzielonej: zależny od implementacji (obecnie 1 bajt,
ale efektywny minimalny rozmiar wynosi PAGE_SIZE).
- SHMMNI
- Systemowy limit liczby segmentów pamięci
dzielonej. W Linuksie 2.2 domyślna wartość tego
limitu wynosiła 128; od Linuksa 2.4 domyślna
wartość wynosi 4096.
- W Linuksie to ograniczenie można odczytać i
zmienić, używając pliku
/proc/sys/kernel/shmmni.
System Linux nie stawia ograniczeń dotyczących liczby
segmentów pamięci dzielonej dołączonych do jednego
procesu (
SHMSEG).
Until Linux 2.3.30, Linux would return
EIDRM for a
shmget() on a
shared memory segment scheduled for deletion.
Nazwa
IPC_PRIVATE prawdopodobnie nie jest najszczęśliwsza.
IPC_NEW w sposób bardziej przejrzysty odzwierciedlałoby
rolę tej wartości.
See
shmop(2).
memfd_create(2),
shmat(2),
shmctl(2),
shmdt(2),
ftok(3),
capabilities(7),
shm_overview(7),
sysvipc(7)
Autorami polskiego tłumaczenia niniejszej strony podręcznika
są: Rafał Lewczuk <
[email protected]>, Andrzej
Krzysztofowicz <
[email protected]>, Robert Luberda
<
[email protected]> i Michał Kułach
<
[email protected]>
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
[email protected]