sem_wait(3) Library Functions Manual sem_wait(3) sem_wait, sem_timedwait, sem_trywait - POSIX threads library (libpthread, -lpthread) #include 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); glibc (. feature_test_macros(7)): sem_timedwait(): _POSIX_C_SOURCE >= 200112L sem_wait() () , sem. , . , , (. ., ), . sem_trywait() sem_wait(), , , (errno EAGAIN), . sem_timedwait() is the same as sem_wait(), except that abs_timeout specifies a limit on the amount of time that the call should block if the decrement cannot be immediately performed. The abs_timeout argument points to a timespec(3) structure that specifies an absolute timeout in seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). , sem_timedwait() (errno ETIMEDOUT). , sem_timedwait() , abs_timeout. , abs_timeout. 0; , -1, errno . EAGAIN (sem_trywait()) The operation could not be performed without blocking (i.e., the semaphore currently has the value zero). EINTR ; signal(7). EINVAL sem . EINVAL (sem_timedwait()) The value of abs_timeout.tv_nsecs is less than 0, or greater than or equal to 1000 million. ETIMEDOUT (sem_timedwait()) The call timed out before the semaphore could be locked. attributes(7). +----------------------------+----------------------------------------------------------+--------------------------+ | | | | +----------------------------+----------------------------------------------------------+--------------------------+ |sem_wait(), sem_trywait(), | | MT-Safe | |sem_timedwait() | | | +----------------------------+----------------------------------------------------------+--------------------------+ POSIX.1-2008. POSIX.1-2001. ( ), , . . , SIGALRM. sem_post(3) , main() sem_timedwait(). sem_timedwait(). : $ ./a.out 2 3 About to call sem_timedwait() sem_post() sem_timedwait() $ ./a.out 2 1 About to call sem_timedwait() sem_timedwait() #include #include #include #include #include #include #include #include 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() from handler\n", 24); if (sem_post(&sem) == -1) { write(STDERR_FILENO, "sem_post() failed\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 \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()\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\n"); else perror("sem_timedwait"); } else printf("sem_timedwait() succeeded\n"); exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE); } clock_gettime(2), sem_getvalue(3), sem_post(3), timespec(3), sem_overview(7), time(7) () Alexander Golubev , Azamat Hackimov , Hotellook, Nikita , Spiros Georgaras , Vladislav , Yuri Kozlov ; GNU (GNU General Public License - GPL, 3 ) , - . - , , () () () <>. Linux 6.9.1 15 2024 . sem_wait(3)