SEMCTL(2) | Podręcznik programisty Linuksa | SEMCTL(2) |
semctl - sterowanie semaforami Systemu V
#include <sys/types.h> #include <sys/ipc.h> #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; /* 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:
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).
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) */ };
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:
Dla wszystkich pozostałych wartości cmd w razie pomyślnego zakończenia zwracane jest 0.
Po niepomyślnym zakończeniu, zmienna errno przyjmie jedną z następujących wartości:
POSIX.1-2001, POSIX.1-2001, 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.
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 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:
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 aktualizuje sempid również przy operacjach SETVAL i dostosowaniach semafora. Jednak, nieco niekonsekwentnie, do wersji 4.5 włącznie, Linux nie aktualizował sempid przy operacjach SETALL. Skorygowano to w Linuksie 4.6.
ipc(2), semget(2), semop(2), capabilities(7), sem_overview(7), svipc(7)
Angielska wersja tej strony pochodzi z wydania 4.07 projektu Linux man-pages. Opis projektu, informacje dotyczące zgłaszania błędów, oraz najnowszą wersję oryginału można znaleźć pod adresem https://www.kernel.org/doc/man-pages/.
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ą 4.07 oryginału.
2016-03-15 | Linux |