В листинге 11.5 приведен текст программы semops, позволяющей выполнять последовательность действий над набором семафоров.

Параметры командной строки

7-19 Параметр –n соответствует установленному флагу IPC_NOWAIT для каждой операции, а параметр –u аналогичным образом позволяет указать для каждой операции флаг SEM_UNDO. Обратите внимание, что функция semop позволяет указывать свой набор флагов для каждого элемента структуры sembuf (то есть для каждой из операций в отдельности), но для простоты мы в нашей программе задаем одинаковые флаги для всех операций.

Выделение памяти под набор операций

20-29 После открытия семафора вызовом semget мы выделяем память под массив структур sembuf, по одному элементу на каждую операцию из командной строки. В отличие от предыдущих двух программ эта позволяет пользователю задать меньше команд, чем имеется семафоров в наборе.

Выполнение операций

30 Вызов semop выполняет последовательность операций над семафорами набора.

Листинг 11.5. Программа semops

//svsem/semops.c

1  #include "unpipc.h"

2  int

3  main(int argc, char **argv)

4  {

5   int с, i, flag, semid, nops;

6   struct sembuf *ptr;

7   flag = 0;

8   while ((c = Getopt(argc, argv, "nu")) != –1) {

9    switch (c) {

10   case 'n':

11    flag |= IPC_NOWAIT; /* для всех операций */

12    break;

13   case 'u':

14    flag |= SEM_UNDO; /* для всех операций */

15    break;

16   }

17  }

18  if (argc = optind 2) /* argc – optind = количество оставшихся аргументов */

19   err_quit("usage: semops [ –n ] [ –u ] pathname operation …");

20  semid = Semget(Ftok(argv[optind], 0), 0, 0);

21  optind++;

22  nops = argc – optind;

23  /* выделение памяти под операции, сохранение их в массиве и выполнение */

24  ptr = Calloc(nops, sizeof(struct sembuf));

25  for (i = 0; i nops; i++) {

26   ptr[i].sem_num = i;

27   ptr[i].sem_op = atoi(argv[optind + i]); /* 0, 0, or 0 */

28   ptr[i].sem_flg = flag;

29  }

30  Semop(semid, ptr, nops);

31  exit(0);

32 }

<p>Примеры</p>

Теперь мы продемонстрируем работу пяти приведенных выше программ и исследуем некоторые свойства семафоров System V:

solaris % touch /tmp/rich

solaris % semcreate –e /tmp/rich 3

solaris % semsetvalues /tmp/rich 1 2 3

solaris % semgetvalues /tmp/rich

semval[0] = 1

semval[1] = 2

semval[2] = 3

Сначала мы создали файл с именем /tmp/rich, который использовался при вызове ftok для вычисления идентификатора набора семафоров. Программа semcreate создает набор с тремя элементами. Программа semsetvalues устанавливает значения этих элементов (1, 2 и 3), a semgetvalues выводит их значения.

Теперь продемонстрируем атомарность выполнения последовательности операций над набором:

solaris % semops –n /tmp/rich –1 –2 –4

semctl error: Resource temporarily unavailable

solaris % semgetvalues /tmp/rich

semval[0] = 1

semval[1] = 2

semval[2] = 3

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже