table of contents
- bookworm-backports 4.25.1-1~bpo12+1
- testing 4.25.1-1
- unstable 4.25.1-1
sem_wait(3) | Library Functions Manual | sem_wait(3) |
NUME¶
sem_wait, sem_timedwait, sem_trywait - blochează un semafor
BIBLIOTECA¶
Biblioteca de fire de execuție POSIX (libpthread, -lpthread)
SINOPSIS¶
#include <semaphore.h>
int sem_wait(sem_t *sem); int sem_trywait(sem_t *sem); int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict abs_timeout);
sem_timedwait():
_POSIX_C_SOURCE >= 200112L
DESCRIERE¶
sem_wait() decrementează (blochează) semaforul indicat de sem. În cazul în care valoarea semaforului este mai mare decât zero, atunci decrementarea are loc, iar funcția returnează, imediat. În cazul în care semaforul are în prezent valoarea zero, apelul se blochează până când fie devine posibilă efectuarea decrementării (de exemplu, valoarea semaforului crește peste zero), fie un gestionar de semnal întrerupe apelul.
sem_trywait() este la fel ca sem_wait(), cu excepția faptului că, dacă decrementarea nu poate fi efectuată imediat, apelul returnează o eroare (errno este configurată la EAGAIN) în loc să blocheze.
sem_timedwait() este la fel ca sem_wait(), cu excepția faptului că abs_timeout specifică o limită de timp în care apelul trebuie blocat dacă decrementarea nu poate fi efectuată imediat. Argumentul abs_timeout indică o structură timespec(3) care specifică un timp de așteptare absolut în secunde și nanosecunde de la Epoch, 1970-01-01 00:00:00 +0000 (UTC).
Dacă timpul de așteptare a expirat deja în momentul apelului, iar semaforul nu a putut fi blocat imediat, atunci sem_timedwait() eșuează cu o eroare de timp (errno este configurată la ETIMEDOUT).
Dacă operația poate fi efectuată imediat, atunci sem_timedwait() nu eșuează niciodată cu o eroare de timp de așteptare, indiferent de valoarea lui abs_timeout. În plus, validitatea lui abs_timeout nu este verificată în acest caz.
VALOAREA RETURNATö
Toate aceste funcții returnează 0 în caz de succes; în caz de eroare, valoarea semaforului rămâne neschimbată, se returnează -1, iar errno este configurată pentru a indica eroarea.
ERORI-IEȘIRE¶
- EAGAIN
- (sem_trywait()) Operația nu a putut fi efectuată fără blocare (de exemplu, semaforul are în prezent valoarea zero).
- EINTR
- Apelul a fost întrerupt de un gestionar de semnal; a se vedea signal(7).
- EINVAL
- semafor nu este un semafor valid.
- EINVAL
- (sem_timedwait()) Valoarea abs_timeout.tv_nsecs este mai mică decât 0 sau mai mare sau egală cu 1000 de milioane.
- ETIMEDOUT
- (sem_timedwait()) Apelul a expirat înainte ca semaforul să poată fi blocat.
ATRIBUTE¶
Pentru o explicație a termenilor folosiți în această secțiune, a se vedea attributes(7).
Interfață | Atribut | Valoare |
sem_wait(), sem_trywait(), sem_timedwait() | Siguranța firelor | MT-Safe |
STANDARDE¶
POSIX.1-2008.
ISTORIC¶
POSIX.1-2001.
EXEMPLE¶
Programul (oarecum trivial) prezentat mai jos operează pe un semafor fără nume. Programul așteaptă două argumente în linia de comandă. Primul argument specifică o valoare în secunde care este utilizată pentru a configura un temporizator de alarmă pentru a genera un semnal SIGALRM. Acest gestionar efectuează un sem_post(3) pentru a incrementa semaforul care este așteptat în main() utilizând sem_timedwait(). Al doilea argument din linia de comandă specifică lungimea timpului de așteptare, în secunde, pentru sem_timedwait(). Ceea ce urmează arată ce se întâmplă la două execuții diferite ale programului:
$ ./a.out 2 3 În curs de apelare a sem_timedwait() sem_post() de la gestionar sem_timedwait() a reușit $ ./a.out 2 1 În curs de apelare a sem_timedwait() ssem_timedwait() a expirat
Sursa programului¶
#include <errno.h> #include <semaphore.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> #include <assert.h> sem_t sem; #define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0) static void handler(int sig) {
write(STDOUT_FILENO, "sem_post() de la gestionar\n", 24);
if (sem_post(&sem) == -1) {
write(STDERR_FILENO, "sem_post() a eșuat\n", 18);
_exit(EXIT_FAILURE);
} } int main(int argc, char *argv[]) {
struct sigaction sa;
struct timespec ts;
int s;
if (argc != 3) {
fprintf(stderr, "Utilizare: %s <secunde-alarmă> <secunde-așteptare>\n",
argv[0]);
exit(EXIT_FAILURE);
}
if (sem_init(&sem, 0, 0) == -1)
handle_error("sem_init");
/* Stabilește gestionarul SIGALRM; fixează temporizatorul de alarmă utilizând argv[1]. */
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGALRM, &sa, NULL) == -1)
handle_error("sigaction");
alarm(atoi(argv[1]));
/* Calculează intervalul relativ ca timp curent plus
numărul de secunde dat de argv[2]. */
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
handle_error("clock_gettime");
ts.tv_sec += atoi(argv[2]);
printf("%s() pe cale să apeleze sem_timedwait()\n", __func__);
while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
continue; /* Repornește dacă este întrerupt de gestionar. */
/* Verifică ce s-a întâmplat. */
if (s == -1) {
if (errno == ETIMEDOUT)
printf("sem_timedwait() timed out\n");
else
perror("sem_timedwait");
} else
printf("sem_timedwait() a reușit\n");
exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE); }
CONSULTAȚI ȘI¶
clock_gettime(2), sem_getvalue(3), sem_post(3), timespec(3), sem_overview(7), time(7)
TRADUCERE¶
Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>
Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.
Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.
15 iunie 2024 | Pagini de manual de Linux 6.9.1 |