Scroll to navigation

SHMGET(2) Podręcznik programisty Linuksa SHMGET(2)

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

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

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.
przekazane łącznie z IPC_CREAT zapewnia sygnalizację błędu, jeśli segment już isnieje.
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

Po wywołaniu fork() proces potomny dziedziczy dołączone segmenty pamięci wspólnej.
Po wywołaniu exec() wszystkie dołączone segmenty są odłączane (nie są usuwane).
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:

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.
jeśli przekazane zostały znaczniki IPC_CREAT | IPC_EXCL , ale segment o zadanym kluczu już istnieje.
jeśli segment został zaznaczony do usunięcia lub usunięty.
jeśli przekroczony został limit ilości segmentów pamięci wspólnej w systemie (SHMMNI) lub sumarycznej wielkości wszystkich segmentów (SHMALL).
jeśli segment o zadanej wartości key nie istnieje, a nie ustawiono znacznika IPC_CREAT.
jeśli użytkownik nie ma praw dostępu do zadanego segmentu pamięci wspólnej.
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:

Maksymalna liczba stron pamięci użytych do stworzenia segmentów pamięci wspólnej: zależna od polityki.
Maksymalny rozmiar (w bajtach) pojedynczego segmentu pamięci wspólnej: zależny od implementacji (aktualnie 4MB).
Minimalny rozmiar (w bajtach) pojedynczego segmentu pamięci wspólnej: zależny od implementacji (aktualnie 1 bajt, ale efektywny minimalny rozmiar wynosi PAGE_SIZE ).
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)

1993-11-28 Linux 0.99.11