SHMGET(2)

NAZWA
shmget - utworzenie segmentu pamięci dzielonej

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

mode_flags
    (9 najmniej znaczących bitów) określa prawa dostępu do segmentu dla jego właściciela, grupy oraz reszty świata. 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.

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

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
Wywołanie to zwraca poprany identyfikator segmentu, shmid, jeżeli zakończy się pomyślnie, lub -1 w przypadku wystąpienia błędu.

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
    Zostały przekazane znaczniki IPC_CREAT | IPC_EXCL i segment o zadanym kluczu już istnieje.

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

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 jest nieprzenośnym rozszerzeniem Linuksa.

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 (w razie powodzenia) utworzy nowy segment pamięci dzielonej.

Następujące ograniczenia odnoszące się do zasobów pamięci dzielonej dotyczą wywołania shmget():

SHMALL
    Maksymalna liczba stron pamięci dzielonej w systemie (pod Linuksem to ograniczenie można odczytać i zmienić, używając pliku /proc/sys/kernel/shmall).

SHMMAX
    Maksymalny rozmiar w bajtach segmentu pamięci dzielonej: wartość zależna od lokalnych ustawień (pod Linuksem 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
    Maksymalna liczba segmentów pamięci dzielonej w systemie: zależna od implementacji (obecnie 4096, ale w wersjach Linuksa wcześniejszych niż 2.3.99 wynosiła 128; pod Linuksem 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.50 projektu Linux man-pages. Opis projektu oraz informacje dotyczące zgłaszania błędów 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.50 oryginału.