NAZWA¶
shmget - utworzenie segmentu pamięci wspólnej
SKŁADNIA¶
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, int size, int
shmflg);
OPIS¶
Uwaga! To tłumaczenie może być nieaktualne!
Funkcja
shmget() zwraca deskryptor segmentu pamięci wspólnej,
skojarzonego z wartością (kluczem) przekazaną w parametrze
key. Nowy segment zostanie utworzony, Jeśli parametr
key
będzie mieć wartość
IPC_PRIVATE lub jeśli
będzie mieć inną wartość, a segment skojarzony z
key nie istnieje zaś w parametrze
shmflg zostanie
przekazany znacznik
IPC_CREAT (tj.
shmflg&IPC_CREAT
nie jest równe 0), to zostanie utworzony nowy segment, a jego rozmiar
będzie równy parametrowi
size zaokrąglonemu w
górę do wielokrotności
PAGE_SIZE.
Wartość
shmflg skłąda się z:
- IPC_CREAT,
- aby utworzyć nowy segment. Jeśli ten znaczniek
nie zostanie ustawiony, to shmget() spróbuje znaleźć
segment skojarzony z key i sprzwdzić, czy użytkownik ma
uprawnienia dla dostępu do segmentu.
- IPC_EXCL
- przekazane łącznie z IPC_CREAT zapewnia
sygnalizację błędu, jeśli segment już
isnieje.
- mode_flags (9 najmniej znaczących
bitów)
- określa prawa dostępu do segmentu dla jego
właściciela, grupy oraz reszty świata. Prawa uruchamiania
nie są obecnie przez system używane.
W momencie tworzenia segmentu, prawa dostępu są kopiowane z parametru
shmflg do pola
shm_perm definiującej segment struktury
shmid_ds. Budowa struktury
shmid_ds:
struct shmid_ds {
struct ipc_perm shm_perm; /* prawa dostępu */
int shm_segsz; /* rozmiar segmentu (w bajtach) */
time_t shm_atime; /* czas ostatniego dołączenia */
time_t shm_dtime; /* czas ostatniego odłączenia */
time_t shm_ctime; /* czas ostatniej modyfikacji */
unsigned short shm_cpid; /* PID twórcy segmentu */
unsigned short shm_lpid; /* PID ostatniego operującego procesu */
short shm_nattch; /* aktualna liczba dołączeń */
};
struct ipc_perm {
key_t key;
ushort uid; /* euid i egid właściciela*/
ushort gid;
ushort cuid; /* euid i egid twórcy */
ushort cgid;
ushort mode; /* 9 najmniej znaczących bitów shmflg */
ushort seq; /* numer porządkowy */
};
Podczas tworzenia segmentu pamięci wsólnej, funkcja ta inicjalizuje
strukturę
shmid_ds w następujący sposób:
- shm_perm.cuid i shm_perm.uid przypisywany
jest efektywny identyfikator użytkownika procesu, który
wywołał shmget.
- shm_perm.cgid i shm_perm.gid przypisywany
jest efektywny identyfikator grupy procesu, który wywołał
shmget.
- 9 najmniej znaczących bitów parametru
shmflg jest kopiowanych do pola shm_perm.mode.
- shm_segsz przypisywana jest wartość
parametru size.
- Polom shm_lpid, shm_nattch, shm_atime
i shm_dtime przypisywana jest wartość 0.
- Polu shm_ctime przypisywany jest aktualny czas.
Jeśli dany segment pamięci wspólnej już istnieje,
wówczas system sprawdza prawa dostępu oraz bada, czy segment nie
został zaznaczony do usunięcia.
WYWOŁANIA SYSTEMOWE¶
- fork()
- Po wywołaniu fork() proces potomny dziedziczy
dołączone segmenty pamięci wspólnej.
- exec()
- Po wywołaniu exec() wszystkie
dołączone segmenty są odłączane (nie są
usuwane).
- exit()
- Podczas wywoływania exit() wszystkie
dołączone segmenty są odłączane (nie są
usuwane).
WARTOŚĆ ZWRACANA¶
Funkcja po pomyślnym zakończeniu zwraca deskryptor segmentu, a -1,
jeśli wystąpi błąd.
BŁĘDY¶
W przypadku wystąpienia błędu, zmiennej
errno przypisywana
jest jedna z następujących wartości:
- EINVAL,
- jeśli miał zostać utworzony nowy segment, a
size < SHMMIN lub size > SHMMAX, lub gdy
nie miał być utworzony nowy segment, a segment o podanej
wartości key istnieje, lecz size jest większe niż
rozmiar tego segmentu.
- EEXIST,
- jeśli przekazane zostały znaczniki IPC_CREAT |
IPC_EXCL , ale segment o zadanym kluczu już istnieje.
- EIDRM
- jeśli segment został zaznaczony do usunięcia
lub usunięty.
- ENOSPC
- jeśli przekroczony został limit ilości
segmentów pamięci wspólnej w systemie (SHMMNI) lub
sumarycznej wielkości wszystkich segmentów (SHMALL).
- ENOENT,
- jeśli segment o zadanej wartości key nie
istnieje, a nie ustawiono znacznika IPC_CREAT.
- EACCES,
- jeśli użytkownik nie ma praw dostępu do
zadanego segmentu pamięci wspólnej.
- ENOMEM,
- gdy nie uda się przydzielić pamięci dla
segmentu.
UWAGI¶
IPC_PRIVATE nie jest znacznikiem, lecz wartością typu
key_t. Jeśli jako
key zostanie użyta ta
wartość specjalna, to funkcja zignoruje wszystko oprócz 9
najmniej znaczących bitów
shmflg i utworzy nowy segment
pamięci wspólnej nie posiadający klucza (jeśli
wywołanie zakończy się pomyślnie).
Następujące ograniczenia odnoszące się do zasobów
pamięci wspólnej dotyczą funkcji
shmget:
- SHMALL
- Maksymalna liczba stron pamięci użytych do
stworzenia segmentów pamięci wspólnej: zależna od
polityki.
- SHMMAX
- Maksymalny rozmiar (w bajtach) pojedynczego segmentu
pamięci wspólnej: zależny od implementacji (aktualnie
4MB).
- SHMMIN
- Minimalny rozmiar (w bajtach) pojedynczego segmentu
pamięci wspólnej: zależny od implementacji (aktualnie 1
bajt, ale efektywny minimalny rozmiar wynosi PAGE_SIZE ).
- SHMMNI
- Maksymalna liczba segmentów pamięci wspólnej
w systemie: zależna od implementacji (aktualnie 4096, ale w wersjach
Linuksa wcześniejszych niż 2.3.99 wynosiła 128)
System Linux nie stawia ograniczeń dotyczących ilości
segmentów dołączonych do jednego procesu (
SHMSEG).
USTERKI¶
Wybrana nazwa, IPC_PRIVATE, prawdopodobnie nie jest najszczęśliwsza.
IPC_NEW w sposób bardziej przejrzysty odzwierciedlało by rolę
tej wartości.
ZGODNE Z¶
SVr4, SVID. SVr4 dokumentuje dodatkowy kod błędu EEXIST. Do wersji
2.3.30 Linux zwracał EIDRM w przepadku wywołania
shmget na
segmencie pamięci wspólnej przeznaczonym do skasowania.
ZOBACZ TAKŻE¶
ftok(3),
ipc(5),
shmctl(2),
shmat(2),
shmdt(2)
Powyższe tłumaczenie pochodzi z nieistniejącego już Projektu
Tłumaczenia Manuali i
może nie być aktualne. W razie
zauważenia różnic między powyższym opisem a
rzeczywistym zachowaniem opisywanego programu lub funkcji, prosimy o
zapoznanie się z oryginalną (angielską) wersją strony
podręcznika za pomocą polecenia:
- man --locale=C 2 shmget
Prosimy o pomoc w aktualizacji stron man - więcej informacji można
znaleźć pod adresem
http://sourceforge.net/projects/manpages-pl/.