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

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

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

59-62 ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ провСряСт ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ всСх элСмСнтов массива ΠΈ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ сообщСниС Π² случаС обнаруТСния ошибки. Как ΡƒΠΆΠ΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΎΡΡŒ, эта функция запускаСтся Π² СдинствСнном экзСмплярС ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ всС ΠΏΠΎΡ‚ΠΎΠΊΠΈ-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ°Ρ‚ свою Ρ€Π°Π±ΠΎΡ‚Ρƒ, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π½Π°Π΄ΠΎΠ±Π½ΠΎΡΡ‚ΡŒ Π² синхронизации отсутствуСт.

ΠŸΡ€ΠΈ запускС Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ описанной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ с ΠΏΡΡ‚ΡŒΡŽ процСссами-производитСлями, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ вмСстС ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΌΠΈΠ»Π»ΠΈΠΎΠ½ элСмСнтов Π΄Π°Π½Π½Ρ‹Ρ…, ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

solaris % prodcons2 1000000 5

count[0] = 167165

count[1] = 249891

count[2] = 194221

count[3] = 191815

count[4] = 196908

Как ΠΌΡ‹ ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π»ΠΈ Ρ€Π°Π½Π΅Π΅, Ссли ΡƒΠ±Ρ€Π°Ρ‚ΡŒ Π²Ρ‹Π·ΠΎΠ² set_concurrency, Π² систСмС Solaris 2.6 Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ count[0] Π±ΡƒΠ΄Π΅Ρ‚ 1000000, Π° всС ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ счСтчики Π±ΡƒΠ΄ΡƒΡ‚ Π½ΡƒΠ»Π΅Π²Ρ‹ΠΌΠΈ.

Если ΡƒΠ±Ρ€Π°Ρ‚ΡŒ ΠΈΠ· этого ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, ΠΎΠ½ пСрСстанСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ ΠΈ прСдполагаСтся. ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ мноТСство элСмСнтов buff[i], значСния ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹ ΠΎΡ‚ i. Π’Π°ΠΊΠΆΠ΅ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚, Ссли Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ.

7.4. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΈ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅

ΠŸΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ, Ρ‡Ρ‚ΠΎ Π²Π·Π°ΠΈΠΌΠ½Ρ‹Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Ρ‹ для блокирования, Π½ΠΎ Π½Π΅ для оТидания. ИзмСним наш ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ Ρ€Π°Π·Π΄Π΅Π»Π° Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ запускался сразу ΠΆΠ΅ послС запуска всСх ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ. Π­Ρ‚ΠΎ даст Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŽ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ ΠΈΡ… формирования производитСлями Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΏpoΠ³Ρ€aΠΌΠΌΡ‹ Π² листингС 7.1, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π½Π΅ запускался Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° всС ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΠΈ Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π»ΠΈ свою Ρ€Π°Π±ΠΎΡ‚Ρƒ. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½Π°ΠΌ придСтся ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ потрСбитСля с производитСлями, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π» Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Π°Π½Π½Ρ‹Π΅, ΡƒΠΆΠ΅ сформированныС послСдними.

Π’ листингС 7.3 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main. Начало ΠΊΠΎΠ΄Π° (Π΄ΠΎ объявлСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main) Π½Π΅ ΠΏΡ€Π΅Ρ‚Π΅Ρ€ΠΏΠ΅Π»ΠΎ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с листингом 7.1.

Листинг 7.3. Ѐункция main: запуск потрСбитСля сразу послС запуска ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ

//mutex/prodcons3.c

14 int

15 main(int argc, char **argv)

16 {

17  int i, nthreads, count[MAXNTHREADS];

18  pthread_t tid_produce[MAXNTHREADS], tid_consume;

19  if (argc != 3)

20   err_quit("usage: prodcons3 <#items> <#threads>");

21  nitems = min(atoi(argv[1]), MAXNITEMS);

22  nthreads = min(atoi(argv[2]), MAXNTHREADS);

23  /* созданиС всСх ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ потрСбитСля */

24  Set_concurrency(nthreads + 1);

25  for (i = 0; i < nthreads; i++) {

26   count[i] = 0;

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

28  }

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

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

31  for (i = 0; i < nthreads; i++) {

32   Pthread_join(tid_produce[i], NULL);

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

34  }

35  Pthread_join(tid_consume, NULL);

36  exit(0);

37 }

24 ΠœΡ‹ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ выполнСния Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΡ‡Π΅ΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊ-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ, выполняСмый ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ с производитСлями.

25-29 ΠŸΠΎΡ‚ΠΎΠΊ-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ создаСтся сразу ΠΆΠ΅ послС создания ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ.

Ѐункция produce ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с листингом 7.2 Π½Π΅ измСняСтся. Π’ листингС 7.4 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ consume, Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ Π½ΠΎΠ²ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ consume_wait. 

Листинг 7.4. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ consume ΠΈ consume_wait

//mutex/prodcons3.с

54 void

55 consume wait(int i)

56 {

57  for (;;) {

58   Pthread_mutex_lock(&shared.mutex);

59   if (i < shared.nput) {

60    Pthread_mutex_unlock(&shared.mutex);

61    return; /* элСмСнт Π³ΠΎΡ‚ΠΎΠ² */

62   }

63   Pthread_mutex_unlock(&shared.mutex);

64  }

65 }


66 void *

67 consume(void *arg)

68 {

69  int i;

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

71   consume_wait(i);

72   if (shared.buff[i] != i)

73    printf("buff[%d] = %d\n", i, shared.buff[i]);

74  }

75  return(NULL);

76 }

ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΆΠ΄Π°Ρ‚ΡŒ

71 ЕдинствСнноС ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ consume Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Π²Ρ‹Π·ΠΎΠ²Π° consume_wait ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ элСмСнта массива.

ОТиданиС ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ

57-64 Наша функция consume_wait Π΄ΠΎΠ»ΠΆΠ½Π° ΠΆΠ΄Π°Ρ‚ΡŒ, ΠΏΠΎΠΊΠ° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΠΈ Π½Π΅ создадут i-ΠΉ элСмСнт. Для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ этого условия производится Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ i сравниваСтся с индСксом производитСля nput. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠ°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ nput ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΎ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π΅Π³ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ.

Главная ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° β€” Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ, Ссли Π½ΡƒΠΆΠ½Ρ‹ΠΉ элСмСнт Π΅Ρ‰Π΅ Π½Π΅ Π³ΠΎΡ‚ΠΎΠ². ВсС, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ остаСтся ΠΈ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΄Π΅Π»Π°Π΅ΠΌ Π² листингС 7.4, β€” это ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π² Ρ†ΠΈΠΊΠ»Π΅, устанавливая ΠΈ снимая Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΈ провСряя Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ индСкса. Π­Ρ‚ΠΎ называСтся опросом (spinning ΠΈΠ»ΠΈ polling) ΠΈ являСтся лишнСй Ρ‚Ρ€Π°Ρ‚ΠΎΠΉ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ процСссора.

ΠœΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ ΠΏΡ€ΠΈΠΎΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ процСсса Π½Π° Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ врСмя, Π½ΠΎ ΠΌΡ‹ Π½Π΅ Π·Π½Π°Π΅ΠΌ, Π½Π° ΠΊΠ°ΠΊΠΎΠ΅. Π§Ρ‚ΠΎ Π½Π°ΠΌ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½ΡƒΠΆΠ½ΠΎ β€” это ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ срСдство синхронизации, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π΅Π΅ ΠΏΠΎΡ‚ΠΎΠΊΡƒ ΠΈΠ»ΠΈ процСссу ΠΏΡ€ΠΈΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ, ΠΏΠΎΠΊΠ° Π½Π΅ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ ΠΊΠ°ΠΊΠΎΠ΅-Π»ΠΈΠ±ΠΎ событиС.

7.5. УсловныС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅: ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ ΠΈ сигнализация

Π’Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для блокирования, Π° условная пСрСмСнная β€” для оТидания. Π­Ρ‚ΠΎ Π΄Π²Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… срСдства синхронизации, ΠΈ ΠΎΠ±Π° ΠΎΠ½ΠΈ Π½ΡƒΠΆΠ½Ρ‹. Условная пСрСмСнная прСдставляСт собой ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Ρ‚ΠΈΠΏΠ° pthread_cond_t. Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ‚Π°ΠΊΠΈΠΌΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Ρ‹ Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ:

#include <pthread.h>

int pthread_cond_wait(pthread_cond_t *cptr, pthread_m_tex_t *mptr);

int pthread_cond_signal(pthread_cond_t *cptr);

/* ОбС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ 0 Π² случаС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ, ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π•Ρ…Ρ…Ρ… – Π² случаС ошибки */

Π‘Π»ΠΎΠ²ΠΎ signal Π² ΠΈΠΌΠ΅Π½ΠΈ Π²Ρ‚ΠΎΡ€ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡ ΠΊ сигналам Unix SIGxxx.

ΠœΡ‹ опрСдСляСм условиС, увСдомлСния ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±ΡƒΠ΄Π΅ΠΌ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ.

Π’Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ всСгда связываСтся с условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ. ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ pthread_cond_wait для оТидания выполнСния ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ условия ΠΌΡ‹ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ адрСс условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈ адрСс связанного с Π½Π΅ΠΉ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ.

ΠœΡ‹ ΠΏΡ€ΠΎΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ использованиС условных ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, пСрСписав ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ Ρ€Π°Π·Π΄Π΅Π»Π°. Π’ листингС 7.5 ΠΎΠ±ΡŠΡΠ²Π»ΡΡŽΡ‚ΡΡ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.

ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ производитСля ΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² структуру

7-13 Π”Π²Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ nput ΠΈ rival Π°ΡΡΠΎΡ†ΠΈΠΈΡ€ΡƒΡŽΡ‚ΡΡ с mutex, ΠΈ ΠΌΡ‹ объСдиняСм ΠΈΡ… Π² структуру с ΠΈΠΌΠ΅Π½Π΅ΠΌ put. Π­Ρ‚Π° структура ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ производитСлями.

14-20 Другая структура, nready, содСрТит счСтчик, ΡƒΡΠ»ΠΎΠ²Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅. ΠœΡ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΡƒΡΠ»ΠΎΠ²Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ PTHREAD_ COND_INITIALIZER.

Ѐункция main ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с листингом 7.3 Π½Π΅ измСняСтся.

Листинг 7.5. Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅: использованиС условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ

//mutex/prodcons6.c

1  #include "unpipc.h"

2  #define MAXNITEMS 1000000

3  #define MAXNTHREADS 100


4  /* Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ для всСх ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */

5  int nitems; /* Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΌ */

6  int buff[MAXNITEMS];


7  struct {

8   pthread_mutex_t mutex;

9   int nput; /* ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ сохраняСмый элСмСнт */

10  int nval; /* ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ сохраняСмоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ */

11 } put = {

12  PTHREAD_MUTEX_INITIALIZER

13 };


14 struct {

15  pthread_mutex_t mutex:

16  pthread_cond_t cond;

17  int nready; /* количСство Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… для потрСбитСля */

18 } nready = {

19  PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER

20 };

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ produce ΠΈ consume ΠΏΡ€Π΅Ρ‚Π΅Ρ€ΠΏΠ΅Π²Π°ΡŽΡ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ измСнСния. Π˜Ρ… тСкст Π΄Π°Π½ Π² листингС 7.6.

Листинг 7.6. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ produce ΠΈ consume

//mutex/prodcons6.c

46 void *

47 produce(void *arg)

48 {

49  for (;;) {

50   Pthread_mutex_lock(&put.mutex);

51   if (put.nput >= nitems) {

52    Pthread_mutex_unlock(&put.mutex);

53    return(NULL); /* массив Π·Π°ΠΏΠΎΠ»Π½Π΅Π½, Π³ΠΎΡ‚ΠΎΠ²ΠΎ */

54   }

55   buff[put.nput] = put.nval;

56   put.nput++;

57   put.nval++;

58   Pthread_mutex_unlock(&put.mutex);

59   Pthread_mutex_lock(&nready.mutex):

60   if (nready.nready == 0)

61    Pthread_cond_signal(&nready.cond);

62   nready.nready++;

63   Pthread_mutex_unlock(&nready.mutex);

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

65  }

66 }


67 void*

68 consume(void *arg)

69 {

70  int i;

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

72   Pthread_mutex_lock(&nready.mutex);

73   while (nready.nready == 0)

74    Pthread_cond_wait(&nready.cond, &nready.mutex);

75   nready.nready--;