| semctl(2) | System Calls Manual | semctl(2) |
semctl - steruje semaforami Systemu V
Standardowa biblioteka C (libc, -lc)
#include <sys/sem.h>
int semctl(int semid, int semnum, int op, ...);
semctl() wykonuje operację sterującą, określoną przez op, 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 op 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 utworzenia/ostatniej zmiany
za pomocą semctl() */
unsigned long sem_nsems; /* Liczba semaforów w zestawie */
};
Pola struktury semid_ds są następujące:
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 */
};
Najmniej znaczące 9 bitów pola mode struktury ipc_perm definiuje uprawnienia dostępu do segmentu pamięci dzielonej. Istnieją następujące bity uprawnień:
| 0400 | Odczyt przez użytkownika |
| 0200 | Zapis przez użytkownika |
| 0040 | Odczyt przez grupę |
| 0020 | Zapis przez grupę |
| 0004 | Odczyt przez pozostałych |
| 0002 | Zapis przez pozostałych |
Dla zestawu semaforów „zapis” znaczy w praktyce „modyfikację”. Bity 0100, 0010 i 0001 (bity praw do uruchamiania) nie są przez system wykorzystywane.
Poprawne wartości parametru op to:
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) */
};
Po pomyślnym zakończeniu, semctl() zwraca nieujemną wartość zależną od parametru op:
Dla wszystkich pozostałych wartości op 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.
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.
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 Linuksa 4.5 włącznie, jądro nie aktualizowało sempid przy operacjach SETALL. Skorygowano to w Linuksie 4.6.
POSIX.1-2008.
POSIX.1-2001, SVr4.
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 op).
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>.
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.
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.
Zobacz shmop(2).
ipc(2), semget(2), semop(2), capabilities(7), sem_overview(7), sysvipc(7)
Tłumaczenie niniejszej strony podręcznika: 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.
| 2 maja 2024 r. | Linux man-pages 6.9.1 |