Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

Стивенс Уильям Ричард

Шрифт:

4 int sem_magic; /* магическое число */

5 } mysem_t;

6 #define SEM_MAGIC 0x89674523

7 #ifdef SEM_FAILED

8 #undef SEM_FAILED

9 #define SEM_FAILED ((mysem_t *)(-1)) /* чтобы компилятор не выдавал предупреждений*/

10 #endif

Тип данных sem_t

1-5 Новая структура данных содержит два дескриптора, один из которых предназначен для чтения из FIFO, а другой — для записи. Для единообразия мы храним оба дескриптора в массиве из двух элементов, в котором первый дескриптор всегда открыт на чтение, а второй — на запись.

Поле sem_magiс содержит значение SEM_MAGIC, если структура проинициализирована. Это значение проверяется всеми функциями, которым передается указатель на тип sem_t, чтобы гарантировать, что передан был действительно указатель на заранее инициализированную структуру, а не на произвольную область памяти. При закрытии семафора этому полю присваивается значение 0. Этот метод хотя и не совершенен, но дает возможность обнаружить некоторые ошибки при написании программ.

Функция 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семафора
  • Читать дальше
  • 1
  • ...
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: