Чтение онлайн

ЖАНРЫ

UNIX: взаимодействие процессов

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

Шрифт:

10.5. Простые примеры

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

Программа semcreate

В листинге 10.3 приведен текст программы, создающей именованный семафор. При вызове программы можно указать параметр –е, обеспечивающий исключающее создание (если семафор уже существует, будет выведено сообщение об ошибке), а параметр –i с числовым

аргументом позволяет задать начальное значение семафора, отличное от 1. 

Листинг 10.3. [1] Создание именованного семафора

//pxsem/semcreate.c

1 #include "unpipc.h"

2 int

3 main(int argc, char **argv)

4 {

5 int с, flags;

6 sem_t *sem;

7 unsigned int value;

8 flags = O_RDWR | O_CREAT;

9 value = 1;

1

Все исходные тексты, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com/download.

10 while ((c = Getopt(argc, argv, "ei:")) != –1) {

11 switch (c) {

12 case 'e':

13 flags |= O_EXCL;

14 break;

15 case 'i':

16 value = atoi(optarg);

17 break;

18 }

19 }

20 if (optind != argc – 1)

21 err_quit("usage: semcreate [ –e ] [ –i initialvalue ] <name>");

22 sem = Sem_open(argv[optind], flags, FILE_MODE, value);

23 Sem_close(sem);

24 exit(0);

25 }

Создание семафора

22 Поскольку мы всегда указываем флаг O_CREAT, нам приходится вызывать sem_open с четырьмя аргументами. Последние два используются только в том случае, если семафор еще не существует.

Закрытие семафора

23 Мы вызываем sem_close, хотя, если бы мы не сделали этот вызов, семафор все равно закрылся бы автоматически при завершении процесса и ресурсы системы были бы высвобождены.

Программа semunlink

Программа в листинге 10.4 удаляет именованный семафор.

Листинг 10.4. Удаление именованного семафора

//pxsem/semunlink.c

1 #include "unpipc.h"

2 int

3 main(int argc, char **argv)

4 {

5 if (argc != 2)

6 err_quit("usage: semunlink <name>");

7 Sem_unlink(argv[1]);

8 exit(0);

9 }

Программа semgetvalue

В листинге 10.5 приведен текст простейшей программы, которая открывает указанный именованный семафор, получает его текущее значение и выводит

его.

Листинг 10.5. Получение и вывод значения семафора

//pxsem/semgetvalue.с

1 #include "unpipc.h"

2 int

3 main(int argc, char **argv)

4 {

5 sem_t *sem;

6 int val;

7 if (argc != 2)

8 err_quit("usage: semgetvalue <name>");

9 sem = Sem_open(argv[1], 0);

10 Sem_getvalue(sem, &val);

11 printf("value = %d\n", val);

12 exit(0);

13 }

Открытие семафора

9 Семафор, который мы открываем, должен быть заранее создан другой программой. Вторым аргументом sem_open будет 0: мы не указываем флаг O_CREAT и нам не нужно задавать никаких других параметров открытия 0_ххх.

Программа semwait

Программа в листинге 10.6 открывает именованный семафор, вызывает semwait (которая приостанавливает выполнение процесса, если значение семафора меньше либо равно 0, а при положительном значении семафора уменьшает его на 1), получает и выводит значение семафора, а затем останавливает свою работу навсегда при вызове pause.

Листинг 10.6. Ожидание изменения значения семафора и вывод нового значения

//pxsem/semwait.c

1 #include "unpipc.h"

2 int

3 main(int argc, char **argv)

4 {

5 sem_t *sem;

6 int val;

7 if (argc != 2)

8 err_quit("usage: semwait <name>");

9 sem = Sem_open(argv[1], 0);

10 Sem_wait(sem);

11 Sem_getvalue(sem, &val);

12 printf("pid %ld has semaphore, value = %d\n", (long) getpid, val);

13 pause; /* блокируется, пока не будет удален */

14 exit(0);

15 }

Программа sempost

В листинге 10.7 приведена программа, которая выполняет операцию post для указанного семафора (то есть увеличивает его значение на 1), а затем получает значение этого семафора и выводит его.

Листинг 10.7. Увеличение значения семафора

//pxsem/sempost.c

1 #include "unpipc.h"

2 int

3 main(int argc, char **argv)

4 {

5 sem_t *sem;

6 int val;

7 if (argc != 2)

8 err_quit("usage: sempost <name>");

9 sem = Sem_open(argv[1], 0);

10 Sem_post(sem);

11 Sem_getvalue(sem, &val);

12 printf("value = %d\n", val);

Поделиться с друзьями: