Пример

Пример

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

Данный текст является ознакомительным фрагментом.