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\n", 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.

<p>10.9. Несколько производителей, один потребитель</p>

Решение в разделе 10.6 относится к классической задаче с одним производителем и одним потребителем. Новая, интересная модификация программы позволит нескольким производителям работать с одним потребителем. Начнем с решения из листинга 10.11, в котором использовались размещаемые в памяти семафоры. В листинге 10.12 приведены объявления глобальных переменных и функция main.

Листинг 10.12. Функция main задачи с несколькими производителями

//pxsem/prodcons3.c

1  #include "unpipc.h"

2  #define NBUFF 10

3  #define MAXNTHREADS 100

4  int nitems, nproducers; /* только для чтения производителем и потребителем */

5  struct { /* общие данные */

6   int buff[NBUFF];

7   int nput;

8   int nputval;

9   sem_t mutex, nempty, nstored; /* семафоры, а не указатели */

10 } shared;

11 void *produce(void *), *consume(void *);

12 int

13 main(int argc, char **argv)

14 {

15  int i, count[MAXNTHREADS];

16  pthread_t tid_produce[MAXNTHREADS], tid_consume;

17  if (argc != 3)

18   err_quit("usage: prodcons3 #items #producers");

19  nitems = atoi(argv[1]);

20  nproducers = min(atoi(argv[2]), MAXNTHREADS);

21  /* инициализация трех семафоров */

22  Sem_init(shared.mutex, 0, 1);

23  Sem_init(shared.nempty, 0, NBUFF);

24  Sem_init(shared.nstored, 0, 0);

25  /* создание всех производителей и одного потребителя */

26  Set_concurrency(nproducers + 1);

27  for (i = 0; i nproducers; i++) {

28   count[i] = 0;

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