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

Пример

Пример

В качестве иллюстрации перепишем наш пример решения задачи производителей и потребителей из листингов 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] = *dn", 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.

Оглавление книги

Оглавление статьи/книги

Генерация: 0.056. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз