NAZWA¶
shmat, shmdt - operacje na segmentach pamięci dzielonej Systemu V
SKŁADNIA¶
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
OPIS¶
shmat()¶
shmat() dołącza segment pamięci dzielonej
Systemu V identyfikowany przez
shmid do przestrzeni adresowej
procesu, który ją wywołał. Adres, pod
którym segment ma być widoczny jest przekazywany w parametrze
shmaddr, przy czym system może przetworzyć ten adres w
następujący sposób:
- *
- Jeśli shmaddr jest równy NULL, to system sam wybierze
odpowiedni (nieużywany) adres, pod którym segment
będzie widoczny.
- *
- Jeśli shmaddr jest różny od NULL i w
shmflg przekazany został znacznik SHM_RND,
wówczas segment zostanie dołączony pod adresem
shmaddr zaokrąglonym w dół do
wielokrotności SHMLBA.
- *
- W innym przypadku shmaddr musi być wyrównanym do
granicy strony adresem, pod którym nastąpi
dołączenie segmentu.
Oprócz
SHM_RND można
określić następujące flagi w argumencie
maski bitowej
shmflg:
- SHM_EXEC (charakterystyczne dla Linuksa; od Linuksa w wersji
2.6.9)
- Pozwala na wykonanie zawartości segmentu. Wywołujący
musi mieć prawo wykonania segmentu.
- SHM_RDONLY
- Dołącza segment do dostępu tylko do odczytu. Proces
wywołujący musi mieć prawa odczytu segmentu.
Jeśli flaga nie jest określona, w dołączanym
segmencie możliwy jest dostęp do odczytu jak i zapisu, przy
czym proces musi mieć prawa do odczytu i zapisu segmentu. Nie
istnieje pojęcie segmentu pamięci dzielonej tylko do
zapisu.
- SHM_REMAP (charakterystyczne dla Linuksa)
- Ten znacznik oznacza, że odwzorowanie tego segmentu powinno
zastąpić jakiekolwiek istniejące wcześniej
odwzorowanie w zakresie rozpoczynającym się od
shmaddr i rozciągającym się na rozmiar
segmentu. (Normalnie, gdy odwzorowanie w tym zakresie adresów
już istnieje, powinien wystąpić błąd
EINVAL). W tym przypadku shmaddr nie może być
równy NULL.
Wartość
brk(2) procesu wywołującego nie jest
zmieniana podczas dołączania segmentu. Segment zostanie
automatycznie odłączony, gdy proces się zakończy.
Ten sam segment może być dołączony do przestrzeni
adresowej procesu jako "tylko do odczytu" lub "do odczytu i
zapisu" więcej niż raz.
Pomyślne wywołanie
shmdt aktualizuje pola struktury
shmid_ds (patrz
shmctl(2)) opisującej segment w
następujący sposób:
- shm_atime przypisywany jest bieżący czas.
- shm_lpid jest ustawiane na identyfikator procesu
wywołującego.
- shm_nattch jest zwiększane o jeden.
shmdt()¶
shmdt odłącza segment pamięci dzielonej odwzorowany
pod adresem podanym w
shmaddr z przestrzeni adresowej procesu
wywołującego tę funkcję. Przekazany funkcji w
parametrze
shmaddr adres musi być równy adresowi
zwróconemu wcześniej przez wywołanie
shmat().
Pomyślne wywołanie
shmdt aktualizuje pola struktury
shmid_ds opisującej segment w następujący
sposób:
- shm_dtime przypisywany jest bieżący czas.
- shm_lpid jest ustawiane na identyfikator procesu
wywołującego.
- shm_nattch jest zmniejszane o jeden. Jeśli pole to
osiągnie 0 i segment jest zaznaczony do usunięcia,
wówczas zostanie on usunięty.
WARTOŚĆ ZWRACANA¶
Jeśli się powiedzie,
shmat() zwraca adres
dołączonego segmentu pamięci dzielonej; w razie
błędu zwracane jest
(void *) -1, a zmienna
errno wskazuje na przyczynę błędu.
Jeśli się powiedzie,
shmdt() zwraca 0; w razie
błędu zwracane jest -1, a zmienna
errno wskazuje na
przyczynę błędu.
BŁĘDY¶
Gdy
shmat() zakończy się niepomyślnie, zmiennej
errno przypisywana jest jedna z następujących
wartości:
- EACCES
- Proces wywołujący nie ma wystarczających
uprawnień do dołączenia segmentu w
żądany sposób oraz nie ma ustawionego atrybutu
CAP_IPC_OWNER.
- EIDRM
- shmid wskazuje na usunięty identyfikator.
- EINVAL
- Niewłaściwa wartość parametru shmid,
niewyrównana (do granicy strony i nie podano SHM_RND) lub
niepoprawna wartość shmaddr albo nieudane
dołączenie pod adresem shmaddr lub został
podany znacznik SHM_REMAP, podczas gdy shmaddr było
równe NULL.
- ENOMEM
- Brak pamięci na deskryptor lub tablice stron.
Gdy
shmdt() zakończy się niepomyślnie, zmiennej
errno przypisywana jest jedna z następujących
wartości:
- EINVAL
- Żaden segment pamięci dzielonej nie jest
podłączony pod adresem shmaddr lub shmaddr nie
jest wyrównany do granicy strony.
ZGODNE Z¶
SVr4, POSIX.1-2001.
W SVID 3 (lub być może wcześniejszym) typ parametru
shmaddr został zmieniony z
char * na
const
void *, a typ wyniku zwracanego przez
shmat() z
char * na
void *.
UWAGI¶
W wyniku wywołania
fork(2) proces potomny dziedziczy
dołączone segmenty pamięci dzielonej.
Po wykonaniu
exec(2) wszystkie dołączone segmenty
pamięci dzielonej są odłączane od procesu.
Po wykonaniu
_exit(2) wszystkie dołączone segmenty
pamięci dzielonej są odłączane od procesu.
Używanie
shmat() z
shmaddr równym NULL jest
zalecaną i przenośną metodą
dołączania segmentu pamięci dzielonej. Trzeba jednak
być świadomym, że ta metoda dołączania
segmentu pamięci dzielonej może spowodować jego
dołączenie pod różnymi adresami w
różnych procesach. W związku z tym wszystkie
wskaźniki obsługiwane w pamięci dzielonej muszą
być względne (zazwyczaj względem adresu
początkowego segmentu), nie zaś bezwzględne.
Linux pozwala na dołączenie segmentu pamięci dzielonej,
nawet jeśli już został zaznaczony do usunięcia.
Jednakże POSIX.1-2001 nie określa takiego zachowania i wiele
innych implementacji go nie obsługuje.
Na wywołanie
shmat() wpływa następujący
parametr systemowy:
- SHMLBA
- Wielokrotność dolnej granicy adresu segmentu. Podczas
bezpośredniego wskazania dołączonego adresu w
wywołaniu do shmat(), wywołujący powinien
się upewnić, że adres jest
wielokrotnością tej wartości. Jest to konieczne w
przypadku niektórych architektur, aby zapewnić dobrą
wydajność pamięci podręcznej procesora lub aby
zapewnić, że różne dołączenia
tego samego segmentu mają spójne widoki w pamięci
podręcznej procesora. SHMLBA jest zwykle jakąś
wielokrotnością systemowego rozmiaru strony (w wielu
architekturach linuksowym jest to wprost systemowy rozmiar strony).
Aktualna implementacja nie ma wewnętrznego ograniczenia na liczbę
segmentów pamięci dzielonej dołączanych do jednego
procesu (
SHMSEG).
ZOBACZ TAKŻE¶
brk(2),
mmap(2),
shmctl(2),
shmget(2),
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.