Функция 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.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Функция SUM

Из книги Обработка баз данных на Visual Basic®.NET автора Мак-Манус Джеффри П

Функция SUM Ваши возможности в подведении итогов не ограничены простым подсчетом записей. Используя функцию SUM, можно генерировать итоговые результаты для всех возвращаемых записей по любым числовым полям. Например, для создания запроса, который генерирует итоги по


Функция uni()

Из книги Fiction Book Designer Краткое руководство автора Автор неизвестен

Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book


Функция uni()

Из книги Fiction Book Designer 3.2. Краткое руководство автора Izekbis

Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book


Функция pthread_rwlock_init

Из книги UNIX: взаимодействие процессов автора Стивенс Уильям Ричард

Функция pthread_rwlock_init Первая функция, pthread_rwlock_init, динамически инициализирует блокировку чтения-записи. Ее текст приведен в листинге 8.2.7-8 Присваивание атрибутов с помощью этой функции не поддерживается, поэтому мы проверяем, чтобы указатель attr был нулевым.9-19 Мы


Функция pthread_rwlock_wrlock

Из книги Технология XSLT автора Валиков Алексей Николаевич

Функция 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

Из книги PGP: Кодирование и шифрование информации с открытым ключом. автора Левин Максим

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

Из книги Fiction Book Designer 3.2. Руководство по созданию книг автора

Функция 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> /* для списков аргументов переменной длины


Хэш-функция.

Из книги автора

Хэш-функция. Еще одно важное преимущество использования PGP состоит в том, что PGP применяет так называемую «хэш-функцию», которая действует таким образом, что в том случае какого-либо изменения информации, пусть даже на один бит, результат «хэш-функции» будет совершенно


Функция uni()

Из книги автора

Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book


Хэш-функция

Из книги автора

Хэш-функция Однако описанная выше схема имеет ряд существенных недостатков. Она крайне медлительна и производит слишком большой объём данных — по меньшей мере вдвое больше объёма исходной информации. Улучшением такой схемы становится введение в процесс преобразования