Manpages

NAZWA

shmget - utworzenie segmentu pamięci dzielonej Systemu V

SKŁADNIA

#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);

OPIS

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.

WARTOŚĆ ZWRACANA

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.

BŁĘDY

W przypadku wystąpienia błędu, zmiennej errno przypisywana jest jedna z następujących wartości:

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

Podano znacznik SHM_HUGETLB, ale proces wywołujący nie był uprzywilejowany (nie miał ustawionego atrybutu CAP_IPC_LOCK).

ZGODNE Z

POSIX.1-2001, POSIX.1-2008, SVr4.

SHM_HUGETLB i SHM_NORESERVE są linuksowymi rozszerzeniami.

UWAGI

Dołączenie <sys/types.h> i <sys/ipc.h> nie jest wymagane na Linuksie ani przez żadną z wersji POSIX. Jednak niektóre stare implementacje wymagają dołączenia tych plików nagłówkowych, SVID również dokumentuje ich dołączenie. Aplikacje które mają być przenośne na tego typu stare systemy mogą wymagać dołączenia omawianych plików nagłówkowych.

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.

Limity 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 MB).

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

Uwagi linuksowe
Do wersji 2.3.30 Linux zwracał EIDRM dla shmget() na segmencie pamięci dzielonej przeznaczonym do usunięcia.

BŁĘDY

Nazwa IPC_PRIVATE prawdopodobnie nie jest najszczęśliwsza. IPC_NEW w sposób bardziej przejrzysty odzwierciedlałoby rolę tej wartości.

PRZYKŁADY

See shmop(2).

ZOBACZ TAKŻE

memfd_create(2), shmat(2), shmctl(2), shmdt(2), ftok(3), capabilities(7), shm_overview(7), sysvipc(7)

O STRONIE

Angielska wersja tej strony pochodzi z wydania 5.07 projektu Linux man-pages. Opis projektu, informacje dotyczące zgłaszania błędów oraz najnowszą wersję oryginału można znaleźć pod adresem https://www.kernel.org/doc/man-pages/.

TŁUMACZENIE

Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Rafał Lewczuk <R.Lewczuk [AT] elka.p>, Andrzej Krzysztofowicz <ankry [AT] green.pl>, Robert Luberda <robert [AT] debian.org> i Michał Kułach <michal.kulach [AT] 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 <manpages-pl-list [AT] lists.net>.