semctl - sterowanie semaforami Systemu V
Standardowa biblioteka C (libc, -lc)
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);
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; /* Ownership and permissions */
time_t sem_otime; /* Last semop time */
time_t sem_ctime; /* Creation time/time of last
modification via semctl() */
unsigned long sem_nsems; /* No. of semaphores in set */
};
Pola struktury semid_ds są
następujące:
- sem_perm
- This is an ipc_perm structure (see below) that specifies the access
permissions on the semaphore set.
- sem_otime
- Czas ostatniego wywołania funkcji systemowej semop(2).
- sem_ctime
- Time of creation of semaphore set or time of last semctl()
IPCSET, SETVAL, or SETALL operation.
- sem_nsems
- Liczba semaforów w zestawie. Każdy semafor zestawu jest
identyfikowany przez nieujemną liczbę
całkowitą z zakresu od 0 do sem_nsems-1.
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 */
};
The least significant 9 bits of the mode field of the
ipc_perm structure define the access permissions for the shared
memory segment. The permission bits are as follows:
0400 |
Read by user |
0200 |
Write by user |
0040 |
Read by group |
0020 |
Write by group |
0004 |
Read by others |
0002 |
Write by others |
In effect, "write" means "alter" for a
semaphore set. Bits 0100, 0010, and 0001 (the execute bits) are unused by
the system.
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
- Write the values of some members of the semid_ds structure pointed
to by arg.buf to the kernel data structure associated with this
semaphore set, updating also its sem_ctime member.
- The following members of the structure are updated: sem_perm.uid,
sem_perm.gid, and (the least significant 9 bits of)
sem_perm.mode.
- The effective UID of the calling process must match the owner
(sem_perm.uid) or creator (sem_perm.cuid) of the semaphore
set, or the caller must be privileged. The argument semnum is
ignored.
- 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.
- SEM_STAT_ANY
(specyficzne dla Linuksa, od Linuksa 4.17)
- Return a semid_ds structure as for SEM_STAT. However,
sem_perm.mode is not checked for read access for semid
meaning that any user can employ this operation (just as any user may read
/proc/sysvipc/sem to obtain the same information).
- 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
- Return the semncnt value for the semnum-th semaphore of the
set (i.e., the number of processes waiting for the semaphore's value to
increase). The calling process must have read permission on the semaphore
set.
- GETPID
- Zwraca wartość sempid skojarzoną z semaforem o
numerze semnum w zestawie. Jest to identyfikator procesu,
który wykonał ostatnią operację
na tym semaforze (ale zob. UWAGI). Proces wywołujący musi
mieć prawa do odczytu zestawu semaforów.
- GETVAL
- Return semval (i.e., the semaphore value) for the semnum-th
semaphore of the set. The calling process must have read permission on the
semaphore set.
- GETZCNT
- Return the semzcnt value for the semnum-th semaphore of the
set (i.e., the number of processes waiting for the semaphore value to
become 0). The calling process must have read permission on the semaphore
set.
- 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.
On success, semctl() returns a nonnegative value depending
on cmd as follows:
- GETNCNT
- wartość semncnt.
- GETPID
- wartość sempid.
- GETVAL
- wartość semval.
- GETZCNT
- wartość semzcnt.
- IPC_INFO
- the index of the highest used entry in the kernel's internal array
recording information about all semaphore sets. (This information can be
used with repeated SEM_STAT or SEM_STAT_ANY operations to
obtain information about all semaphore sets on the system.)
- SEM_INFO
- tak jak IPC_INFO.
- SEM_STAT
- identyfikator zestawu semaforów, którego indeks
został podany w semid.
- SEM_STAT_ANY
- tak jak SEM_STAT.
Dla wszystkich pozostałych wartości cmd w
razie pomyślnego zakończenia zwracane jest 0.
W razie błędu semctl() zwraca -1, a zmiennej
errno zostanie nadana wartość określająca
rodzaj błędu.
- EACCES
- The argument cmd has one of the values GETALL,
GETPID, GETVAL, GETNCNT, GETZCNT,
IPC_STAT, SEM_STAT, SEM_STAT_ANY, SETALL, or
SETVAL and the calling process does not have the required
permissions on the semaphore set and does not have the
CAP_IPC_OWNER capability in the user namespace that governs its IPC
namespace.
- 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.
POSIX.1-2001, POSIX.1-2008, SVr4.
POSIX.1 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.
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 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.
POSIX.1 definiuje sempid jako "identyfikator procesu
ostatniej operacji" na semaforze i wprost zauważa, że
wartość tak jest ustawiana przez pomyślne
wywołanie semop(2), z implikacją, że
żaden inny interfejs nie wpływa na wartość
sempid.
Choć niektóre implementacje są zgodne
z zachowaniem opisanym w POSIX.1, to inne nie są (błąd
prawdopodobnie leży tu w specyfikacji POSIX.1, jako że nie
zauważyła ona tylu przykładów
istniejących implementacji). Różne inne implementacje
aktualizują sempid również przy innych
operacjach aktualizujących wartość semafora: operacjach
SETVAL i SETALL, jak
również dostosowaniach semafora wykonywanych przy
zakończeniu procesu jako konsekwencji użycia flagi
SEM_UNDO (zob. semop(2)).
Linux also updates sempid for SETVAL operations and
semaphore adjustments. However, somewhat inconsistently, up to and including
Linux 4.5, the kernel did not update sempid for SETALL
operations. This was rectified in Linux 4.6.
Autorami polskiego tłumaczenia niniejszej strony
podręcznika są: Rafał Lewczuk
<R.Lewczuk@elka.pw.edu.p>, Andrzej Krzysztofowicz
<ankry@green.mf.pg.gda.pl>, Robert Luberda <robert@debian.org> i
Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną
dokumentacją. Bliższe informacje o warunkach licencji
można uzyskać zapoznając się z
GNU General
Public License w wersji 3 lub nowszej. Nie przyjmuje się
ŻADNEJ ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika
prosimy zgłaszać na adres listy dyskusyjnej
manpages-pl-list@lists.sourceforge.net.