NAZWA¶
shmop - operacje na segmentach pamięci wspólnej
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¶
Uwaga! To tłumaczenie może być nieaktualne!
Funkcja
shmat dołącza segment pamięci wspólnej o
deskryptorze
shmid do przestrzeni adresowej procesu, który ją
wywołał. Adres, pod którym segment ma być widoczny jest
przekazywany parametrem
shmaddr, przy czym system może
przetworzyć ten adres w następujący sposób:
Jeśli
shmaddr jest równy
NULL, wówczas system sam
wybierze odpowiedni (nieużywany) adres, pod którym segment
będzie widoczny.
Jeśli
shmaddr nie jest równy
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 razie
shmaddr musi być wyrównanym do granicy strony adresem, pod
którym nastąpi dołączenie segmentu.
Jeśli w
shmflg przekazany zostanie znacznik
SHM_RDONLY,
wówczas segment zostanie odwzorowany z zabezpieczeniem przed zapisem.
Proces wywołujący
shmat musi mieć prawa odczytu
segmentu. W przeciwnym razie w dołączanym segmencie możliwe
są zarówno odczyt, jak i zapis, przy czym proces musi mieć
prawa do odczytu i zapisu segmentu. Nie istnieje pojęcie segmentu
pamięci wspólnej tylko do zapisu.
Znacznik (specyficzny dla Linuksa)
SHM_REMAP, który może
zostać przekazany w
shmflg 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 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 byc równe
NULL.
Wartość
brk procesu wywołującego funkcję nie
jest zmieniana podczas dołączania segmentu. Segment zostanie
automatycznie odłączony, gdy proces zakończy się. 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.
W wyniku pomyślnego wywołania
shmat system operacyjny
aktualizuje pola struktury
shmid_ds opisującej segment w
następujący sposób:
- shm_atime zostaje przypisany aktualny czas.
- shm_lpid zostanie przypisany identyfikator procesu
wywołującego shmat.
- shm_nattch zostanie zwiększone o jeden.
Należy zwrócić uwagę, że operacja powiedzie się
nawet jeśli dołączany segment pamięci wspólnej jest
zaznaczony do usunięcia.
Funkcja
shmdt wyłącza segment pamięci wspólnej
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 .
W wyniku pomyślnego wywołania
shmdt pola struktury
shmid_ds opisującej segment aktualizowane są w
następujący sposób:
- shm_dtime przypisywany jest aktualny czas.
- shm_lpid przypisywany jest identyfikator procesu
wywołującego shmdt.
- 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.
Obszar w przestrzeni adresowej procesu wywołującego funkcję jest
zwalniany.
WYWOŁANIA SYSTEMOWE¶
- fork()
- W wyniku wywołania fork() proces potomny
dziedziczy dołączone segmenty pamięci wspólnej.
- exec()
- Po wykonaniu exec() wszystkie odwzorowane segmenty
są odłączane (nie są usuwane).
- exit()
- Po wykonaniu exit() wszystkie dołączone
segmenty pamięci wspólnej są odłączane (nie
są usuwane).
WARTOŚĆ ZWRACANA¶
W przypadku wystąpienia błędu opydwie funkcje zwracają
-1 przypisując zmiennej
errno kod błędu. W wyniku
poprawnego wykonania funkcja
shmat zwraca adres początku obszaru
odwzorowania segmentu, natomiast funkcja
shmdt zwraca wartość
0.
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 funkcję nie ma
uprawnień do dołączenia segmentu w zadany sposób (do
odczytu lub odczytu / zapisu).
- EINVAL
- Niewłaściwa wartość parametru
shmid, niewyrównana do granicy strony (i nie podano
SHM_RND), niepoprawna wartość shmaddr, nieudane
dołączenie pod adresem brk lub został podany
znacznik SHM_REMAP, podczas gdy shmaddr jest równe
NULL.
- ENOMEM
- Brak pamięci na deskryptor lub tablice stron.
Funkcja
shmdt może zakończyć się niepomyślnie
tylko w sytuacji, gdy pod adresem
shmaddr nie istnieje segment
pamięci wspólnej. Wowczas zmienna
errno przyjmie
wartość
EINVAL.
UWAGI¶
Używanie
shmat z
shmaddr równym
NULL jest
zalecaną, przenośną motodą dołączania segmentu
pamięci wspólnej. Trzeba jednak być świadomym, że ta
metoda dołączania segmentu pamięci wspólnej 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 wspólnej muszą być
względne (zazwyczaj względem adresu początkowego segmentu), nie
zaś bezwzględne.
Dla wywołania
shmat obowiązuje następujące
ograniczenie systemowe:
- SHMLBA
- Wartość, której wielokrotnością
musi być adres dolnej granicy segmentu. Musi być wyrównana
do granicy strony. W aktualnej implementacji SHMLBA jest równe
PAGE_SIZE.
Aktualna implementacja nie ma wewnętrznego ograniczenia na ilość
segmentów pamięci wspólnej dołączanych do jednego
procesu (
SHMSEG).
ZGODNE Z¶
SVr4, SVID. SVr4 dokumentuje dodatkowy kod błędu EMFILE. W SVID-v4 typ
parametru
shmaddr został zmieniony z
char * na
const
void *, a typ wyniku zwracanego przez
shmat() z
char * na
void *. (Linuksowe libc4 i libc5 zawierają prototypy
char
*; glibc2 zawiera
void *.)
ZOBACZ TAKŻE¶
brk(2),
ipc(5),
mmap(2),
shmctl(2),
shmget(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 shmop
Prosimy o pomoc w aktualizacji stron man - więcej informacji można
znaleźć pod adresem
http://sourceforge.net/projects/manpages-pl/.