Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX: взаимодСйствиС процСссов». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 62

Автор Уильям БтивСнс

//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\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.

10.9. НСсколько ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ, ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ

РСшСниС Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 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;

29   Pthread_create(&tid_produce[i], NULL, produce, &count[i]);

30  }

31  Pthread_create(&tid_consume, NULL, consume, NULL);

32  /* ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ всСх ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ ΠΈ потрСбитСля */

33  for (i = 0; i < nproducers; i++) {

34   Pthread_join(tid_produce[i], NULL);

35   printf("count[%d] = %d\n", i, count[i]);

36  }

37  Pthread_join(tid_consume, NULL);

38  Sem_destroy(&shared.mutex);

39  Sem_destroy(&shared.nempty);

40  Sem_destroy(&shared.nstored);

41  exit(0);

42 }

Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅

4 Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Π°Ρ пСрСмСнная nitems Ρ…Ρ€Π°Π½ΠΈΡ‚ число элСмСнтов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ совмСстно ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½Ρ‹. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ nproducers Ρ…Ρ€Π°Π½ΠΈΡ‚ число ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ. Оба эти значСния ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки.

ΠžΠ±Ρ‰Π°Ρ структура

5-10 Π’ структуру shared Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ Π΄Π²Π° Π½ΠΎΠ²Ρ‹Ρ… элСмСнта: nput, ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‰ΠΈΠΉ индСкс ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ элСмСнта, ΠΊΡƒΠ΄Π° Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ (ΠΏΠΎ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ BUFF), ΠΈ nputval β€”ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΎ Π² Π±ΡƒΡ„Π΅Ρ€. Π­Ρ‚ΠΈ Π΄Π²Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ взяты ΠΈΠ· нашСго Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π² листингах 7.1 ΠΈ 7.2. Они Π½ΡƒΠΆΠ½Ρ‹ для синхронизации Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ.

НовыС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки

17-20 Π”Π²Π° Π½ΠΎΠ²Ρ‹Ρ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ ΠΏΠΎΠ»Π½ΠΎΠ΅ количСство элСмСнтов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½Ρ‹ Π² Π±ΡƒΡ„Π΅Ρ€, ΠΈ количСство ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ. 

Запуск всСх ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

21-41 Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ сСмафоры ΠΈ запускаСм ΠΏΠΎΡ‚ΠΎΠΊΠΈ-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΠΈ ΠΈ ΠΏΠΎΡ‚ΠΎΠΊ-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ. Π—Π°Ρ‚Π΅ΠΌ оТидаСтся Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². Π­Ρ‚Π° Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠΎΠ΄Π° практичСски ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Π° листингу 7.1.

Π’ листингС 10.13 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ produce, которая выполняСтся ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΌ.

Листинг 10.13. Ѐункция, выполняСмая всСми ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ-производитСлями

//pxsem/prodcons3.c

43 void *

44 produce(void *arg)

45 {

46  for (;;) {

47   Sem_wait(&shared.nempty); /* ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ освобоТдСния поля */

48   Sem_wait(&shared.mutex);

49   if (shared.nput >= nitems) {

50    Sem_post(&shared.nempty);

51    Sem_post(&shared.mutex);

52    return(NULL); /* Π³ΠΎΡ‚ΠΎΠ²ΠΎ */

53   }

54   shared.buff[shared.nput % NBUFF] = shared.nputval;

55   shared.nput++;

56   shared.nputval++;

57   Sem_post(&shared.mutex);

58   Sem_post(&shared.nstored); /* Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ элСмСнт */

59   *((int *) arg) += 1;

60  }

61 }

Π’Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ-производитСлями

49-53 ΠžΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ листинга 10.8 Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ρ†ΠΈΠΊΠ» Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ, ΠΊΠΎΠ³Π΄Π° nitems ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΎ Π² Π±ΡƒΡ„Π΅Ρ€ всСми ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΈ-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ сСмафор nempty Π² любой ΠΌΠΎΠΌΠ΅Π½Ρ‚, Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ сСмафор mutex. Π­Ρ‚ΠΎ Π·Π°Ρ‰ΠΈΡ‰Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ nput ΠΈ nval ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ измСнСния нСсколькими производитСлями.

Π—Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ

50-51 Нам Π½ΡƒΠΆΠ½ΠΎ Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ. ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ послСдний ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ Π² Π±ΡƒΡ„Π΅Ρ€, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ выполняСт

Sem_wait(&shared.nempty); /* ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ пустого поля */

Π² Π½Π°Ρ‡Π°Π»Π΅ Ρ†ΠΈΠΊΠ»Π°, Ρ‡Ρ‚ΠΎ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сСмафора nempty. Но ΠΏΡ€Π΅ΠΆΠ΄Π΅, Ρ‡Π΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½, ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ этого сСмафора, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π² Π±ΡƒΡ„Π΅Ρ€ Π² послСднСм ΠΏΡ€ΠΎΡ…ΠΎΠ΄Π΅ Ρ†ΠΈΠΊΠ»Π°. Π—Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠΉ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΠΎΡ‚ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ сСмафор mutex, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΠΈ смогли ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅. Если ΠΌΡ‹ Π½Π΅ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠΌ сСмафор nempty ΠΏΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ процСсса ΠΈ Ссли ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ большС, Ρ‡Π΅ΠΌ мСст Π² Π±ΡƒΡ„Π΅Ρ€Π΅, Π»ΠΈΡˆΠ½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ навсСгда, оТидая освобоТдСния сСмафора nempty, ΠΈ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Ρ‚ свою Ρ€Π°Π±ΠΎΡ‚Ρƒ.

Ѐункция consume Π² листингС 10.14 провСряСт ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΡŒ всСх записСй Π² Π±ΡƒΡ„Π΅Ρ€Π΅, выводя сообщСниС ΠΏΡ€ΠΈ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠΈ ошибки.

Листинг 10.14. Ѐункция, выполняСмая ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ

//pxsem/prodcons3.с

62 void *

63 consume(void *arg)

64 {

65  int i;

66  for (i = 0; i < nitems; i++) {

67   Sem_wait(&shared.nstored); /* ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ помСщСния ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ элСмСнта Π² Π±ΡƒΡ„Π΅Ρ€ */

68   Sem_wait(&shared.mutex);

69   if (shared.buff[i % NBUFF] != i)

70    printf("error: buff[%d] = %d\n", i, shared.buff[i % NBUFF]);

71   Sem_post(&shared.mutex);

72   Sem_post(&shared.nempty); /* Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΎ пустоС ΠΏΠΎΠ»Π΅ */

73  }

74  return(NULL);

75 }

УсловиС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ СдинствСнного ΠΏΠΎΡ‚ΠΎΠΊΠ°-потрСбитСля Π·Π²ΡƒΡ‡ΠΈΡ‚ просто: ΠΎΠ½ считаСт всС ΠΏΠΎΡ‚Ρ€Π΅Π±Π»Π΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈ останавливаСтся ΠΏΠΎ достиТСнии nitems.

10.10. НСсколько ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ, нСсколько ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΡ‹ внСсСм Π² Π½Π°ΡˆΡƒ ΠΏpoΠ³Ρ€aΠΌΠΌy, Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒΡΡ Π² Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ возмоТности ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ вмСстС с нСсколькими производитСлями. Π•ΡΡ‚ΡŒ Π»ΠΈ смысл Π² Π½Π°Π»ΠΈΡ‡ΠΈΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ β€” зависит ΠΎΡ‚ прилоТСния. Автор Π²ΠΈΠ΄Π΅Π» Π΄Π²Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… использовался этот ΠΌΠ΅Ρ‚ΠΎΠ΄.