Функция sem_open
Функция sem_open
В листинге 10.22 приведен текст функции sem_open, которая создает новый семафор или открывает существующий.
Листинг 10.22. Функция sem_open
//my_pxsem_fifo/sem_open.с
1 #include "unpipc.h"
2 #include "semaphore.h"
3 #include <stdarg.h> /* для произвольного списка аргументов */
4 mysem_t *
5 mysem_open(const char *pathname, int oflag, …)
6 {
7 int i, flags, save_errno;
8 char c;
9 mode_t mode;
10 va_list ap;
11 mysem_t *sem;
12 unsigned int value;
13 if (oflag & O_CREAT) {
14 va_start(ap, oflag); /* ар инициализируется последним аргументом */
15 mode = va_arg(ap, va_mode_t);
16 value = va_arg(ap, unsigned int);
17 va_end(ap);
18 if (mkfifo(pathname, mode) < 0) {
19 if (errno == EEXIST && (oflag & O_EXCL) == 0)
20 oflag &= ~O_CREAT; /* уже существует, OK */
21 else
22 return(SEM_FAILED);
23 }
24 }
25 if ((sem = malloc(sizeof(mysem_t))) == NULL)
26 return(SEM_FAILED);
27 sem->sem_fd[0] = sem->sem_fd[1] = –1;
28 if ((sem->sem_fd[0] = open(pathname, O_RDONLY | O_NONBLOCK)) < 0)
29 goto error;
30 if ((sem->sem_fd[1] = open(pathname, O_WRONLY | O_NONBLOCK)) < 0)
31 goto error;
32 /* отключение неблокируемого режима для sem_fd[0] */
33 if ((flags = fcntl(sem->sem_fd[0], F_GETFL, 0)) < 0)
34 goto error;
35 flags &= ~O_NONBLOCK;
36 if (fcntl(sem->sem_fd[0], F_SETFL, flags) < 0)
37 goto error;
38 if (oflag & O_CREAT) { /* инициализация семафора */
39 for (i = 0; i < value; i++)
40 if (write(sem->sem_fd[1], &c, 1) != 1)
41 goto error;
42 }
43 sem->sem_magic = SEM_MAGIC;
44 return(sem);
45 error:
46 save_errno = errno;
47 if (oflag & O_CREAT)
48 unlink(pathname); /* если мы создали FIFO */
49 close(sem->sem_fd[0]); /* игнорируем ошибку */
50 close(sem->sem_fd[1]); /* игнорируем ошибку */
51 free(sem);
52 errno = save_errno;
53 return(SEM_FAILED);
54 }
Создание нового sсемафора
13-17 Если при вызове указан флаг O_CREAT, должно быть указано четыре аргумента, а не два. Мы вызываем va_start, после чего переменная ар указывает на последний явно указанный аргумент (oflag). Затем мы используем ар и функцию va_arg для получения значений третьего и четвертого аргументов. Работу со списком аргументов переменной длины и использование нашего типа va_mode_t мы обсуждали в связи с листингом 5.17.
Создание нового канала FIFO
18-23 Создается новый канал FIFO, имя которого было указано при вызове функции. Как мы отмечали в разделе 4.6, эта функция возвращает ошибку EEXIST, если канал уже существует. Если при вызове sem_open флаг O_EXCL не был указан, мы пропускаем эту ошибку; но нам не нужно будет инициализировать этот канал, так что мы при этом сбрасываем флаг O_CREAT.
Выделение памяти под тип sem_t и открытие FIFO на чтение и запись
25-37 Мы выделяем место для типа sem_t, который содержит два дескриптора. Затем мы дважды открываем канал FIFO: один раз только на чтение, а другой — только на запись. При этом мы не хотим блокирования при вызове open, поэтому указываем флаги O_NONBLOCK при открытии очереди только для чтения (вспомните табл. 4.1). Мы также указываем флаг O_NONBLOCK при открытии канала на запись, но это предназначено для обнаружения переполнения (на тот случай, если мы попытаемся записать больше, чем позволяет PIPE_BUF). После открытия канала мы отключаем неблокируемый режим для дескриптора, открытого на чтение.
Инициализация значения созданного семафора
38-42 Если мы создали семафор, его нужно проинициализировать, записав в канал FIFO value байтов. Если указанное при вызове значение value превышает определенное реализацией ограничение PIPE_BUF, вызов write после переполнения FIFO вернет ошибку с кодом EAGAIN.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
Функция pthread_rwlock_init
Функция pthread_rwlock_init Первая функция, pthread_rwlock_init, динамически инициализирует блокировку чтения-записи. Ее текст приведен в листинге 8.2.7-8 Присваивание атрибутов с помощью этой функции не поддерживается, поэтому мы проверяем, чтобы указатель attr был нулевым.9-19 Мы
Функция pthread_rwlock_wrlock
Функция pthread_rwlock_wrlock Текст функции pthread_rwlock_wrlock приведен в листинге 8.6.11-17 Если ресурс заблокирован на считывание или запись (значение rw_refcount отлично от 0), мы приостанавливаем выполнение потока. Для этого мы увеличиваем rw_nwaitwriters и вызываем pthread_cond_wait с условной переменной
10.2. Функции sem_open, sem_close и sem_unlink
10.2. Функции sem_open, sem_close и sem_unlink Функция sem_open создает новый именованный семафор или открывает существующий. Именованный семафор может использоваться для синхронизации выполнения потоков и процессов:#include <semaphore.h>sem_t *sem_open(const char *name, int oflag, … /* mode_t mode, unsigned int value */);/*
Функция sem_open
Функция sem_open В листинге 10.28 приведен текст первой части функции sem_open, которая может использоваться для создания нового семафора или открытия существующего.Листинг 10.28. Функция sem_open: первая половина//my_pxsem_mmap/sem_open.с1 #include "unpipc.h"2 #include "semaphore.h"3 #include <stdarg.h> /* для списков
Функция sem_open
Функция sem_open В листинге 10.37 приведен текст первой половины функции sem_open, которая создает новый семафор или открывает существующий.Листинг 10.37. Функция sem_open: первая часть//my_pxsem_svsem/sem_open. с1 #include "unpipc.h"2 #include "semaphore.h"3 #include <stdarg.h> /* для списков аргументов переменной длины
Функция SUM
Функция SUM Ваши возможности в подведении итогов не ограничены простым подсчетом записей. Используя функцию SUM, можно генерировать итоговые результаты для всех возвращаемых записей по любым числовым полям. Например, для создания запроса, который генерирует итоги по
Функция uni()
Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book
Функция uni()
Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book
Хэш-функция.
Хэш-функция. Еще одно важное преимущество использования PGP состоит в том, что PGP применяет так называемую «хэш-функцию», которая действует таким образом, что в том случае какого-либо изменения информации, пусть даже на один бит, результат «хэш-функции» будет совершенно
Функция uni()
Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book
Хэш-функция
Хэш-функция Однако описанная выше схема имеет ряд существенных недостатков. Она крайне медлительна и производит слишком большой объём данных — по меньшей мере вдвое больше объёма исходной информации. Улучшением такой схемы становится введение в процесс преобразования