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