Пример
Пример
В качестве иллюстрации перепишем наш пример решения задачи производителей и потребителей из листингов 10.8 и 10.9 для использования размещаемых в памяти семафоров Posix. В листинге 10.11 приведен текст новой программы.
Листинг 10.11. Задача производителей и потребителей с использованием размещаемых в памяти семафоров
//pxsem/prodcons2.c
1 #include "unpipc.h"
2 #define NBUFF 10
3 int nitems; /* только для чтения производителем и потребителем */
4 struct { /* общие данные производителя и потребителя */
5 int buff[NBUFF];
6 sem_t mutex, nempty, nstored; /* семафоры, а не указатели */
7 } shared;
8 void *produce(void *), *consume(void *);
9 int
10 main(int argc, char **argv)
11 {
12 pthread_t tid_produce, tid_consume;
13 if (argc != 2)
14 err_quit("usage: prodcons2 <#items>");
15 nitems = atoi(argv[1]);
16 /* инициализация трех семафоров */
17 Sem_init(&shared.mutex, 0, 1);
18 Sem_init(&shared.nempty, 0, NBUFF);
19 Sem_init(&shared.nstored, 0, 0);
20 Set_concurrency(2);
21 Pthread_create(&tid_produce, NULL, produce, NULL);
22 Pthread_create(&tid_consume, NULL, consume, NULL);
23 Pthread_join(tid_produce, NULL);
24 Pthread_join(tid_consume, NULL):
25 Sem_destroy(&shared.mutex);
26 Sem_destroy(&shared.nempty):
27 Sem_destroy(&shared.nstored);
28 exit(0);
29 }
30 void *
31 produce(void *arg)
32 {
33 int i;
34 for (i = 0; i < nitems; i++) {
35 Sem_wait(&shared.nempty); /* ожидание одного свободного поля */
36 Sem_wait(&shared.mutex);
37 shared.buff[i % NBUFF] = i; /* помещение i в циклический буфер */
38 Sem_post(&shared.mutex);
39 Sem_post(&shared.nstored); /* поместили еще один элемент */
40 }
41 return(NULL);
42 }
43 void *
44 consume(void *arg)
45 {
46 int i;
47 for (i = 0; i < nitems; i++) {
48 Sem_wait(&shared.nstored); /* ожидаем появления хотя бы одного готового для обработки элемента */
49 Sem_wait(&shared.mutex);
50 if (shared.buff[i % NBUFF] != i)
51 printf("buff[*d] = *d ", i, shared.buff[i % NBUFF]);
52 Sem_post(&shared.mutex);
53 Sem_post(&shared.nempty); /* еще одно пустое поле */
54 }
55 return(NULL);
56 }
Выделение семафоров
6 Мы объявляем три семафора типа sem_t, и теперь это сами семафоры, а не указатели на них.
Вызов sem_init
16-27 Мы вызываем sem_init вместо sem_open* а затем sem_destroy вместо sem_unlink. Вызывать sem_destroy на самом деле не требуется, поскольку программа все равно завершается.
Остальные изменения обеспечивают передачу указателей на три семафора при вызовах sem_wait и sem_post.
Данный текст является ознакомительным фрагментом.