.\" -*- coding: UTF-8 -*- '\" t .\" Copyright (C) 2006 Michael Kerrisk .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH sem_wait 3 "15 июня 2024 г." "Справочные страницы Linux 6.9.1" .SH ИМЯ sem_wait, sem_timedwait, sem_trywait \- блокирует семафор .SH БИБЛИОТЕКА POSIX threads library (\fIlibpthread\fP, \fI\-lpthread\fP) .SH СИНТАКСИС .nf \fB#include \fP .P \fBint sem_wait(sem_t *\fP\fIsem\fP\fB);\fP \fBint sem_trywait(sem_t *\fP\fIsem\fP\fB);\fP \fBint sem_timedwait(sem_t *restrict \fP\fIsem\fP\fB,\fP \fB const struct timespec *restrict \fP\fIabs_timeout\fP\fB);\fP .fi .P .RS -4 Требования макроса тестирования свойств для glibc (см. \fBfeature_test_macros\fP(7)): .RE .P \fBsem_timedwait\fP(): .nf _POSIX_C_SOURCE >= 200112L .fi .SH ОПИСАНИЕ Функция \fBsem_wait\fP() уменьшает (блокирует) семафор, на который указывает \fIsem\fP. Если значение семафор больше нуля, то выполняется уменьшение и функция сразу завершается. Если значение семафора равно нулю, то вызов блокируется до тех пор, пока не станет возможным выполнить уменьшение (т. е., значение семафора не станет больше нуля), или пока не вызовется обработчик сигнала. .P Функция \fBsem_trywait\fP() подобна \fBsem_wait\fP(), за исключением того, что если уменьшение нельзя выполнить сразу, то вызов завершается с ошибкой (\fIerrno\fP становится равным \fBEAGAIN\fP), а не блокируется. .P \fBsem_timedwait\fP() is the same as \fBsem_wait\fP(), except that \fIabs_timeout\fP specifies a limit on the amount of time that the call should block if the decrement cannot be immediately performed. The \fIabs_timeout\fP argument points to a \fBtimespec\fP(3) structure that specifies an absolute timeout in seconds and nanoseconds since the Epoch, 1970\-01\-01 00:00:00 +0000 (UTC). .P Если на момент вызова время ожидания уже истекло и семафор нельзя заблокировать сразу, то \fBsem_timedwait\fP() завершается с ошибкой просрочки (\fIerrno\fP становится равным \fBETIMEDOUT\fP). .P Если операцию можно выполнить сразу, то \fBsem_timedwait\fP() никогда не завершится с ошибкой просрочки, независимо от значения \fIabs_timeout\fP. Кроме того, в этом случае не проверяется корректность \fIabs_timeout\fP. .SH "ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ" При успешном выполнении все функции возвращают 0; при ошибке значение семафора не изменяется, возвращается \-1, а в \fIerrno\fP указывается причина ошибки. .SH ОШИБКИ .TP \fBEAGAIN\fP (\fBsem_trywait\fP()) The operation could not be performed without blocking (i.e., the semaphore currently has the value zero). .TP \fBEINTR\fP Вызов был прерван обработчиком сигнала; смотрите \fBsignal\fP(7). .TP \fBEINVAL\fP Значение \fIsem\fP не является корректным для семафора. .TP \fBEINVAL\fP (\fBsem_timedwait\fP()) The value of \fIabs_timeout.tv_nsecs\fP is less than 0, or greater than or equal to 1000 million. .TP \fBETIMEDOUT\fP .\" POSIX.1-2001 also allows EDEADLK -- "A deadlock condition .\" was detected", but this does not occur on Linux(?). (\fBsem_timedwait\fP()) The call timed out before the semaphore could be locked. .SH АТРИБУТЫ Описание терминов данного раздела смотрите в \fBattributes\fP(7). .TS allbox; lbx lb lb l l l. Интерфейс Атрибут Значение T{ .na .nh \fBsem_wait\fP(), \fBsem_trywait\fP(), \fBsem_timedwait\fP() T} Безвредность в нитях MT\-Safe .TE .SH СТАНДАРТЫ POSIX.1\-2008. .SH ИСТОРИЯ POSIX.1\-2001. .SH ПРИМЕРЫ Программа (несколько упрощённая), показанная ниже, работает с безымянным семафором. Она ожидает два аргумента командной строки. В первом аргументе задаётся значение в секундах, которое используется в будильнике для генерации сигнала \fBSIGALRM\fP. Этот обработчик выполняет \fBsem_post\fP(3) для увеличения семафора, которого ждёт в \fImain()\fP вызов \fBsem_timedwait\fP(). Во втором аргументе задаётся период ожидания в секундах для \fBsem_timedwait\fP(). Далее показано что происходит в двух разных запусках программы: .P .in +4n .EX $\fB ./a.out 2 3\fP About to call sem_timedwait() sem_post() из обработчика sem_timedwait() выполнена успешно $\fB ./a.out 2 1\fP About to call sem_timedwait() истекло время ожидания sem_timedwait() .EE .in .SS "Исходный код программы" .\" SRC BEGIN (sem_wait.c) \& .EX #include #include #include #include #include #include #include \& #include \& sem_t sem; \& #define handle_error(msg) \[rs] do { perror(msg); exit(EXIT_FAILURE); } while (0) \& static void handler(int sig) { write(STDOUT_FILENO, "sem_post() from handler\[rs]n", 24); if (sem_post(&sem) == \-1) { write(STDERR_FILENO, "sem_post() failed\[rs]n", 18); _exit(EXIT_FAILURE); } } \& int main(int argc, char *argv[]) { struct sigaction sa; struct timespec ts; int s; \& if (argc != 3) { fprintf(stderr, "Usage: %s \[rs]n", argv[0]); exit(EXIT_FAILURE); } \& if (sem_init(&sem, 0, 0) == \-1) handle_error("sem_init"); \& /* Establish SIGALRM handler; set alarm timer using 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])); \& /* Calculate relative interval as current time plus number of seconds given argv[2]. */ \& if (clock_gettime(CLOCK_REALTIME, &ts) == \-1) handle_error("clock_gettime"); \& ts.tv_sec += atoi(argv[2]); \& printf("%s() about to call sem_timedwait()\[rs]n", __func__); while ((s = sem_timedwait(&sem, &ts)) == \-1 && errno == EINTR) continue; /* Restart if interrupted by handler. */ \& /* Check what happened. */ \& if (s == \-1) { if (errno == ETIMEDOUT) printf("sem_timedwait() timed out\[rs]n"); else perror("sem_timedwait"); } else printf("sem_timedwait() succeeded\[rs]n"); \& exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE); } .EE .\" SRC END .SH "СМОТРИТЕ ТАКЖЕ" \fBclock_gettime\fP(2), \fBsem_getvalue\fP(3), \fBsem_post\fP(3), \fBtimespec\fP(3), \fBsem_overview\fP(7), \fBtime\fP(7) .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства разработал(и) Alexander Golubev , Azamat Hackimov , Hotellook, Nikita , Spiros Georgaras , Vladislav , Yuri Kozlov и Иван Павлов . .PP Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, .UR https://www.gnu.org/licenses/gpl-3.0.html .UE версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ. .PP Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу .MT списка рассылки русских переводчиков .ME .