Scroll to navigation

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);

Cerințe pentru macrocomenzi de testare a caracteristicilor pentru glibc (consultați feature_test_macros(7)):

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

(sem_trywait()) Operația nu a putut fi efectuată fără blocare (de exemplu, semaforul are în prezent valoarea zero).
Apelul a fost întrerupt de un gestionar de semnal; a se vedea signal(7).
semafor nu este un semafor valid.
(sem_timedwait()) Valoarea abs_timeout.tv_nsecs este mai mică decât 0 sau mai mare sau egală cu 1000 de milioane.
(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