NAZWA¶
semctl - sterowanie semaforami Systemu V
SKŁADNIA¶
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);
OPIS¶
semctl() wykonuje operację sterującą
określoną przez
cmd na zestawie semaforów
Systemu V określonym przez
semid lub na semaforze o
numerze
semnum z tego zestawu. (Numeracja semaforów w zestawie
semaforów zaczyna się od 0).
W zależności od
cmd funkcja przyjmuje trzy lub cztery
argumenty. Jeśli są cztery, to czwarty jest typu
union
semun.
Program wywołujący musi zdefiniować
tę unię jako:
union semun {
int val; /* Wartość dla SETVAL */
struct semid_ds *buf; /* Bufor dla IPC_STAT, IPC_SET */
unsigned short *array; /* Tablica dla GETALL, SETALL */
struct seminfo *__buf; /* Bufor dla IPC_INFO
(specyficzne dla Linuksa) */
};
Struktura danych
semid_ds jest zdefiniowana w
<sys/sem.h>
następująco:
struct semid_ds {
struct ipc_perm sem_perm; /* Prawa dostępu */
time_t sem_otime; /* Czas ostatniej operacji semop */
time_t sem_ctime; /* Czas ostatniej zmiany */
unsigned long sem_nsems; /* Liczba semaforów w zestawie */
};
Struktura
ipc_perm jest zdefiniowana następująco
(wyróżnione pola można ustawić za pomocą
IPC_SET):
struct ipc_perm {
key_t __key; /* Klucz podany w semget(2) */
uid_t uid; /* Efektywny UID właściciela */
gid_t gid; /* Efektywny GID właściciela */
uid_t cuid; /* Efektywny UID twórcy */
gid_t cgid; /* Efektywny GID twórcy */
unsigned short mode; /* Uprawnienia */
unsigned short __seq; /* Numer sekwencji */
};
Poprawne wartości parametru
cmd to:
- IPC_STAT
- Kopiuje informacje ze struktury kontrolnej jądra skojarzonej z
semid do struktury semid_ds wskazywanej przez
arg.__buf. Argument semnum jest ignorowany.
Wywołujący musi mieć uprawnienie odczytu zestawu
semaforów.
- IPC_SET
- Zapisuje wartości niektórych pól struktury
semid_ds wskazywanej przez arg.__buf do struktury danych
jądra powiązanej z tym zestawem semaforów,
aktualizując także pole sem_ctime.
Następujące pola mogą być zmieniane:
sem_perm.uid, sem_perm.gid oraz (9 najmniej
znaczących bitów pola) sem_perm.mode. Efektywny
identyfikator użytkownika procesu wywołującego musi
być równy identyfikatorowi właściciela (
sem_perm.uid) lub twórcy ( sem_perm.cuid) segmentu
pamięci dzielonej albo proces wywołujący musi
być uprzywilejowany. Argument semnum jest ignorowany.
- IPC_RMID
- Usuwa natychmiast zestaw semaforów. Wznawia wszystkie procesy
zablokowane w wywołaniu semop(2) (wywołanie to
zasygnalizuje błąd i ustawi zmienną errno na
EIDRM). Efektywny identyfikator użytkownika procesu
wywołującego musi odpowiadać twórcy lub
właścicielowi zestawu semaforów albo proces
wywołujący musi być uprzywilejowany. Argument
semnum jest pomijany.
- IPC_INFO (specyficzne dla Linuksa)
- Zwraca w strukturze, na którą wskazuje arg.__buf,
informacje o systemowych ograniczeniach i parametrach semaforów.
Struktura jest typu seminfo i jest zdefiniowana w
<sys/shm.h>, pod warunkiem, że zdefiniowano
również makro _GNU_SOURCE:
struct seminfo {
int semmap; /* Liczba wpisów w mapie semaforów
nieużywane przez jądro */
int semmni; /* Maksymalna liczba zestawów semaforów */
int semmns; /* Maksymalna liczba semaforów we wszystkich
zestawach semaforów */
int semmnu; /* Maksymalna liczba struktur wycofania (undo)
w systemie; nieużywane przez jądro*/
int semmsl; /* Maksymalna liczba semaforów
w zestawie */
int semopm; /* Maksymalna liczba operacji dla
semop(2) */
int semume; /* Maksymalna liczba wpisów wycofania (undo)
procesu; nieużywane przez jądro */
int semusz; /* Rozmiar struktury sem_undo */
int semvmx; /* Maksymalna wartość semafora */
int semaem; /* Maksymalna wartość możliwa do zapamiętania
dla regulacji semafora (SEM_UNDO) */
};
Ustawienia semmsl, semmns, semopm oraz semmni
można zmienić za pomocą plików w
/proc/sys/kernel/sem; szczegóły można
znaleźć w podręczniku proc(5).
- SEM_INFO (specyficzne dla Linuksa)
- Zwraca strukturę seminfo zawierającą te same
informacje co w przypadku IPC_INFO, z tym wyjątkiem,
że w następujących polach zwracane są
informacje o zasobach systemowych wykorzystywanych przez semafory: pole
semusz zwraca liczbę zestawów semaforów
istniejących obecnie w systemie; pole semaem zwraca
całkowitą liczbę semaforów we wszystkich
zestawach semaforów w systemie.
- SEM_STAT (specyficzne dla Linuksa)
- Zwraca strukturę semid_ds, taką jak dla
IPC_STAT. Jednakże parametr semid nie jest
identyfikatorem segmentu, ale indeksem wewnętrznej tablicy
jądra przechowującej informacje o wszystkich segmentach
zestawach semaforów w systemie.
- GETALL
- Zwraca (bieżącą) wartość semval
dla wszystkich semaforów z zestawu, umieszczając je w
tablicy arg.array. Argument semnum jest pomijany. Proces
wywołujący musi mieć prawa do odczytu zestawu
semaforów.
- GETNCNT
- Zwraca wartość semncnt skojarzoną z semaforem
numer semnum (tzn. liczbę procesów
oczekujących na zwiększenie się wartości
semval skojarzonej z semaforem numer semnum). Proces
wywołujący musi mieć prawa do odczytu zestawu
semaforów.
- GETPID
- Zwraca wartość sempid skojarzoną z semaforem o
numerze semnum w zestawie (jest to identyfikator procesu,
który ostatnio wykonał semop(2) na semaforze o
numerze semnum). Proces wywołujący musi mieć
prawa do odczytu zestawu semaforów.
- GETVAL
- Zwraca wartość semval semafora o numerze
semnum w zestawie semaforów. Proces wywołujący
musi mieć prawa do odczytu zestawu semaforów.
- GETZCNT
- Zwraca wartość semzcnt skojarzoną z semaforem
o numerze semnum w zestawie (tzn. liczbę procesów
oczekujących na osiągnięcie przez semafor o numerze
semnum wartości 0). Proces wywołujący musi
mieć prawa do odczytu zestawu semaforów.
- SETALL
- Przypisuje wartości semval wszystkim semaforom zestawu,
korzystając z tablicy arg.array, jednocześnie
aktualizuje pole sem_ctime struktury semid_ds skojarzonej z
zestawem. Wpisy wycofania (undo; patrz semop(2)) są
czyszczone dla wszystkich zmienianych semaforów we wszystkich
procesach. Jeżeli zmiany wartości semaforów
pozwoliłyby na odblokowanie procesów oczekujących w
wywołaniach semop(2), to te procesy są wznawiane.
Argument semnum jest pomijany. Proces wywołujący musi
mieć prawa do modyfikacji (zapisu) zestawu semaforów.
- SETVAL
- Przypisuje wartość semval do arg.val semafora
o numerze semnum w zestawie, aktualizując
jednocześnie pole sem_ctime struktury semid_ds
skojarzonej z zestawem semaforów. Wpisy wycofania (undo) są
czyszczone dla zmienianych semaforów we wszystkich procesach.
Jeżeli zmiany wartości semaforów pozwoliłyby
na odblokowanie procesów oczekujących w wywołaniach
semop(2), to te procesy są wznawiane. Proces
wywołujący funkcję musi mieć prawa do
modyfikacji zestawu semaforów.
WARTOŚĆ ZWRACANA¶
W razie błędu
semctl() zwraca -1, a zmiennej
errno
zostanie nadana wartość określająca rodzaj
błędu.
W przeciwnym przypadku zwrócona zostanie nieujemna wartość
zależna od parametru
cmd:
- GETNCNT
- wartość semncnt.
- GETPID
- wartość sempid.
- GETVAL
- wartość semval.
- GETZCNT
- wartość semzcnt.
- IPC_INFO
- indeks najwyższego używanego wpisu w wewnętrznej
tablicy jądra przechowującej informacje o wszystkich
zestawach semaforów. (Informacji tej można
użyć w operacjach SEM_STAT, aby otrzymać
informacje o wszystkich zestawach semaforów w systemie).
- SEM_INFO
- tak jak IPC_INFO.
- SEM_STAT
- identyfikator zestawu semaforów, którego indeks
został podany w semid.
Dla wszystkich pozostałych wartości
cmd w razie
pomyślnego zakończenia zwracane jest 0.
BŁĘDY¶
Po niepomyślnym zakończeniu, zmienna
errno przyjmie
jedną z następujących wartości:
- EACCES
- Parametr cmd ma jedną z wartości GETALL,
GETPID, GETVAL, GETNCNT, GETZCNT,
IPC_STAT, SEM_STAT, SETALL lub SETVAL, a
proces wywołujący nie ma wystarczających
uprawnień do działania na zbiorze semaforów oraz nie
ma ustawionego atrybutu CAP_IPC_OWNER.
- EFAULT
- Adres wskazywany przez arg.buf lub arg.array jest
niedostępny.
- EIDRM
- Zestaw semaforów został usunięty.
- EINVAL
- Niepoprawna wartość parametru cmd lub semid.
Albo: w przypadku operacji SEM_STAT wartość indeksu
podana w parametrze semid odwoływała się do
obecnie nieużywanego elementu tablicy.
- EPERM
- Parametr cmd jest równy IPC_SET lub IPC_RMID,
ale identyfikator efektywnego użytkownika procesu
wywołującego nie jest twórcą
(określonym w sem_perm.cuid) ani właścicielem
(określonym w sem_perm.uid) zestawu semaforów, a
proces nie ma ustawionego atrybutu CAP_SYS_ADMIN.
- ERANGE
- Argument cmd ma wartość SETALL lub
SETVAL, ale przekazywana wartość semafora
semval (dla któregoś z semaforów zestawu) jest
mniejsza od 0 lub większa od wartości ograniczenia
systemowego SEMVMX.
ZGODNE Z¶
SVr4, POSIX.1-2001.
POSIX.1-2001 określa pole
sem_nsems struktury
semid_ds jako
będące typu
unsigned short i tak też jest
ono zdefiniowane w większości systemów. Tak było
również w Linuksie 2.2 i wcześniejszych, lecz od Linuksa
2.4 pole to jest typu
unsigned long.
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.
Operacje
IPC_INFO,
SEM_STAT oraz
SEM_INFO są
używane przez program
ipcs(1) w celu dostarczenia informacji o
zajmowanych zasobach. W przyszłości operacje te mogą
zostać zmodyfikowane lub przeniesione do interfejsu systemu
plików
/proc.
Niektóre pola struktury
struct semid_ds były w Linuksie 2.2
typu
short, ale stały się typu
long w Linuksie
2.4. Aby to wykorzystać, powinna wystarczyć rekompilacja pod
glibc-2.1.91 lub nowszą. (Jądro rozróżnia stare
wywołania od nowych za pomocą znacznika
IPC_64 w
cmd).
We wcześniejszych wersjach biblioteki glibc unia
semun była
zdefiniowana w
<sys/sem.h>, jednakże POSIX.1-2001 wymaga,
żeby to program wywołujący definiował tę
unię. Wersje glibc, które
nie definiują tej unii,
definiują makro
_SEM_SEMUN_UNDEFINED w
<sys/sem.h>.
Na wywołanie
semctl() wpływa następujące
ograniczenie systemowe dotyczące zbioru semaforów:
- SEMVMX
- Maksymalna wartość semval: zależna od
implementacji (32767).
W celu uzyskania lepszej przenośności, najlepiej zawsze
wywoływać
semctl() z czterema argumentami.
ZOBACZ TAKŻE¶
ipc(2),
semget(2),
semop(2),
capabilities(7),
sem_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.