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() zwraca identyfikator segmentu pamięci dzielonej
Systemu V, skojarzonego z wartością (kluczem)
przekazaną w parametrze
key. Nowy segment, o rozmiarze
równym wartości parametru
size zaokrąglonym w
górę do wielokrotności
PAGE_SIZE, zostanie
utworzony, jeśli parametr
key będzie mieć
wartość
IPC_PRIVATE lub jeśli będzie
mieć inną wartość oraz segment skojarzony z
key nie istnieje, a w parametrze
shmflg zostanie przekazany
znacznik
IPC_CREAT.
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)
- Dołącza segment używając "wielkich
stron" (huge pages). Dalsze informacje można
znaleźć w pliku Documentation/vm/hugetlbpage.txt w
źródłach jądra Linux.
- 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
- Użytkownik nie ma praw dostępu do żądanego
segmentu pamięci dzielonej oraz nie ma ustawionego atrybutu
CAP_IPC_OWNER.
- 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ż SHMIN 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¶
SVr4, POSIX.1-2001.
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 liczby stron pamięci dzielonej. Od Linuksa 2.4
domyślna wartość tego limitu wynosi
SHMMAX / PAGE_SIZE * (SHMMNI / 16)
Jeśli SHMMAX i SHMMNI nie
są zmodyfikowane, określa limit całkowitej
pamięci używanej przez wszystkie segmenty pamięci
dzielonej o rozmiarze 8 GB: przy rozmiarze strony 4 kB, ta formuła
określa wartość 2^21 (2 097 152); przy rozmiarze
strony 8 kB jest to 2^20 (1 048 576).
W Linuksie to ograniczenie można odczytać i zmienić,
używając pliku /proc/sys/kernel/shmall.
- SHMMAX
- Maksymalny rozmiar segmentu pamięci dzielonej w bajtach. Od Linuksa
2.2 domyślna wartość tego limitu wynosi 0x2000000 (32
MB).
W Linuksie to ograniczenie można odczytać i zmienić,
używając pliku /proc/sys/kernel/shmmax.
- 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.
USTERKI¶
Nazwa
IPC_PRIVATE prawdopodobnie nie jest najszczęśliwsza.
IPC_NEW w sposób bardziej przejrzysty odzwierciedlałoby
rolę tej wartości.
ZOBACZ TAKŻE¶
shmat(2),
shmctl(2),
shmdt(2),
ftok(3),
capabilities(7),
shm_overview(7),
svipc(7)
O STRONIE¶
Angielska wersja tej strony pochodzi z wydania 3.71 projektu Linux
man-pages. Opis projektu, informacje dotyczące zgłaszania
błędów, oraz najnowszą wersję
oryginału można znaleźć pod adresem
http://www.kernel.org/doc/man-pages/.
TŁUMACZENIE¶
Autorami polskiego tłumaczenia niniejszej strony podręcznika man
są: Rafał Lewczuk (PTM) <R.Lewczuk@elka.pw.edu.p>, Andrzej
Krzysztofowicz (PTM) <ankry@mif.pg.gda.pl>, Robert Luberda
<robert@debian.org> i Michał Kułach
<michal.kulach@gmail.com>.
Polskie tłumaczenie jest częścią projektu
manpages-pl; uwagi, pomoc, zgłaszanie błędów na
stronie
http://sourceforge.net/projects/manpages-pl/. Jest zgodne z
wersją
3.71 oryginału.