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

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

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

1. Π’ нашСм ΠΏΠ΅Ρ€Π²ΠΎΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ (Ρ€Π°Π·Π΄Π΅Π» 7.2) ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ запускался Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ, поэтому ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ синхронизации, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ СдинствСнноС Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ для синхронизации ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ.

2. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ (Ρ€Π°Π·Π΄Π΅Π» 7.5) ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ запускался Π΄ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ, поэтому Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π»ΠΎΡΡŒ использованиС Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ (для синхронизации ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ) вмСстС с условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈ Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΈΠΌ Π²Π·Π°ΠΈΠΌΠ½Ρ‹ΠΌ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ (для синхронизации потрСбитСля с производитСлями).

Π Π°ΡΡˆΠΈΡ€ΠΈΠΌ постановку Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΎΠ±Ρ‰ΠΈΠΉ Π±ΡƒΡ„Π΅Ρ€ Π² качСствС цикличСского: Π·Π°ΠΏΠΎΠ»Π½ΠΈΠ² послСднСС ΠΏΠΎΠ»Π΅, ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ (buff[NBUFF-1]) возвращаСтся ΠΊ Π΅Π³ΠΎ Π½Π°Ρ‡Π°Π»Ρƒ ΠΈ заполняСт ΠΏΠ΅Ρ€Π²ΠΎΠ΅ ΠΏΠΎΠ»Π΅ (buff[0]), ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ дСйствуСт Ρ‚Π°ΠΊΠΈΠΌ ΠΆΠ΅ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ. Π’ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΎ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊ синхронизации: ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΠΏΠ΅Ρ€Π΅ΠΆΠ°Ρ‚ΡŒ производитСля. ΠœΡ‹ всС Π΅Ρ‰Π΅ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ собой ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ процСсса, Π½ΠΎ ΠΎΠ½ΠΈ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈ просто ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ процСссами, Ссли ΠΌΡ‹ смоТСм ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ для Π½ΠΈΡ… ΠΎΠ±Ρ‰ΠΈΠΉ Π±ΡƒΡ„Π΅Ρ€ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ€Π°Π·Π΄Π΅Π»ΡΠ΅ΠΌΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ, Ρ‡Π°ΡΡ‚ΡŒ 4).

ΠŸΡ€ΠΈ использовании ΠΎΠ±Ρ‰Π΅Π³ΠΎ Π±ΡƒΡ„Π΅Ρ€Π° Π² качСствС цикличСского ΠΊΠΎΠ΄ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡ‚ΡŒ Ρ‚Ρ€Π΅ΠΌ трСбованиям:

1. ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π°, Ссли Π±ΡƒΡ„Π΅Ρ€ пуст.

2. ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π² Π±ΡƒΡ„Π΅Ρ€, Ссли послСдний ΠΏΠΎΠ»ΠΎΠ½.

3. Π‘остояниС Π±ΡƒΡ„Π΅Ρ€Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒΡΡ ΠΎΠ±Ρ‰ΠΈΠΌΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ (индСксами, счСтчиками, указатСлями связных списков ΠΈ Ρ‚.Π΄.), поэтому всС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с Π±ΡƒΡ„Π΅Ρ€ΠΎΠΌ, ΡΠΎΠ²Π΅Ρ€ΡˆΠ°Π΅ΠΌΡ‹Π΅ потрСбитСлями ΠΈ производитСлями, Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Ρ‹ ΠΎΡ‚ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ ситуации Π³ΠΎΠ½ΠΎΠΊ.

НашС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚Ρ€ΠΈ сСмафора:

1. Π‘ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ сСмафор с ΠΈΠΌΠ΅Π½Π΅ΠΌ mutex Π·Π°Ρ‰ΠΈΡ‰Π°Π΅Ρ‚ критичСскиС области ΠΊΠΎΠ΄Π°: ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… Π² Π±ΡƒΡ„Π΅Ρ€ (для производитСля) ΠΈ ΠΈΠ·ΡŠΡΡ‚ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π° (для потрСбитСля). Π‘ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ сСмафор, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ Π² качСствС Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, инициализируСтся Π΅Π΄ΠΈΠ½ΠΈΡ†Π΅ΠΉ. (ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ Π²Π·Π°ΠΈΠΌΠ½Ρ‹ΠΌ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ вмСсто Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ³ΠΎ сСмафора. Π‘ΠΌ. ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 10.10.)

2. Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€-счСтчик с ΠΈΠΌΠ΅Π½Π΅ΠΌ nempty подсчитываСт количСство свободных ΠΏΠΎΠ»Π΅ΠΉ Π² Π±ΡƒΡ„Π΅Ρ€Π΅. Он инициализируСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, Ρ€Π°Π²Π½Ρ‹ΠΌ ΠΎΠ±ΡŠΠ΅ΠΌΡƒ Π±ΡƒΡ„Π΅Ρ€Π° (NBUFF).

3. Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€-счСтчик с ΠΈΠΌΠ΅Π½Π΅ΠΌ nstored подсчитываСт количСство Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Ρ… ΠΏΠΎΠ»Π΅ΠΉ Π² Π±ΡƒΡ„Π΅Ρ€Π΅. Он инициализируСтся Π½ΡƒΠ»Π΅ΠΌ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π±ΡƒΡ„Π΅Ρ€ пуст.

Рис. 10.7. БостояниС Π±ΡƒΡ„Π΅Ρ€Π° ΠΈ Π΄Π²ΡƒΡ… сСмафоров-счСтчиков послС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ


На рис. 10.7 ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ состояниС Π±ΡƒΡ„Π΅Ρ€Π° ΠΈ Π΄Π²ΡƒΡ… сСмафоров-счСтчиков послС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. ΠΠ΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ элСмСнты массива Π²Ρ‹Π΄Π΅Π»Π΅Π½Ρ‹ Ρ‚Π΅ΠΌΠ½Ρ‹ΠΌ.

Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π² Π±ΡƒΡ„Π΅Ρ€ Ρ†Π΅Π»Ρ‹Π΅ числа ΠΎΡ‚ 0 Π΄ΠΎ NLOOP-1 (buff[0] = 0, buff[1] = 1), работая с Π½ΠΈΠΌ ΠΊΠ°ΠΊ с цикличСским. ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ считываСт эти числа ΠΈ провСряСт ΠΈΡ… ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΡŒ, выводя сообщСния ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ… Π² стандартный ΠΏΠΎΡ‚ΠΎΠΊ Π²Ρ‹Π²ΠΎΠ΄Π°.

На рис. 10.8 ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΎ состояниС Π±ΡƒΡ„Π΅Ρ€Π° ΠΈ сСмафоров-счСтчиков послС помСщСния Π² Π±ΡƒΡ„Π΅Ρ€ Ρ‚Ρ€Π΅Ρ… элСмСнтов, Π½ΠΎ Π΄ΠΎ ΠΈΠ·ΡŠΡΡ‚ΠΈΡ ΠΈΡ… ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ.

Рис. 10.8. Π‘ΡƒΡ„Π΅Ρ€ ΠΈ сСмафоры послС помСщСния Π² Π±ΡƒΡ„Π΅Ρ€ Ρ‚Ρ€Π΅Ρ… элСмСнтов


ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ изъял ΠΎΠ΄ΠΈΠ½ элСмСнт ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π°. НовоС состояниС ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΎ Π½Π° рис. 10.9.

Рис. 10.9. Π‘ΡƒΡ„Π΅Ρ€ ΠΈ сСмафоры послС удалСния ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ элСмСнта ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π°


Π’ листингС 10.8 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main, которая создаСт Ρ‚Ρ€ΠΈ сСмафора, запускаСт Π΄Π²Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ ΠΈΡ… Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΈ удаляСт сСмафоры.

Листинг 10.8. Ѐункция main для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ сСмафоров

//pxsem/prodcons1.с

1  #include "unpipc.h"

2  #define NBUFF 10

3  #define SEM_MUTEX "mutex" /* Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ px_ipc_name() */

4  #define SEM_NEMPTY "nempty"

5  #define SEM_NSTORED "nstored"


6  int nitems; /* read-only для производитСля ΠΈ потрСбитСля */

7  struct { /* раздСляСмыС ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΌ ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ */

8   int buff[NBUFF];

9   sem_t *mutex, *nempty, *nstored;

10 } shared;

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


12 int

13 main(int argc, char **argv)

14 {

15  pthread_t tid_produce, tid_consume;

16  if (argc != 2)

17   err_quit("usage: prodcons1 <#items>");

18  nitems = atoi(argv[1]);

19  /* созданиС Ρ‚Ρ€Π΅Ρ… сСмафоров */

20  shared.mutex = Sem_open(Px_ipc_name(SEM_MUTEX), O_CREAT | O_EXCL,

21   FILE_MODE, 1);

22  shared.nempty = Sem_open(Px_ipc_name(SEM_NEMPTY), 0_CREAT | O_EXCL,

23   FILE_MODE, NBUFF);

24  shared.nstored = Sem_open(Px_ipc_name(SEM_NSTORED), O_CREAT | O_EXCL,

25   FILE_MODE, 0);

26  /* созданиС ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°-производитСля ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°-потрСбитСля */

27  Set_concurrency(2);

28  Pthread_create(&tid_produce, NULL, produce, NULL);

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

30  /* ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */

31  Pthread_join(tid_produce, NULL);

32  Pthread_join(tid_consume, NULL);

33  /* ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ сСмафоров */

34  Sem_unlink(Px_ipc_name(SEM_MUTEX));

35  Sem_unlink(Px_ipc_name(SEM_NEMPTY));

36  Sem_unlink(Px_ipc_name(SEM_NSTORED));

37  exit(0);

38 }

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

6-10 ΠŸΠΎΡ‚ΠΎΠΊΠΈ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π±ΡƒΡ„Π΅Ρ€, содСрТащий NBUFF элСмСнтов, ΠΈ Ρ‚Ρ€ΠΈ указатСля Π½Π° сСмафоры. Как Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΎΡΡŒ Π² Π³Π»Π°Π²Π΅ 7, ΠΌΡ‹ объСдиняСм эти Π΄Π°Π½Π½Ρ‹Π΅ Π² структуру, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ΄Ρ‡Π΅Ρ€ΠΊΠ½ΡƒΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ сСмафоры ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для синхронизации доступа ΠΊ Π±ΡƒΡ„Π΅Ρ€Ρƒ.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ сСмафоров

19-25 ΠœΡ‹ создаСм Ρ‚Ρ€ΠΈ сСмафора, пСрСдавая ΠΈΡ… ΠΈΠΌΠ΅Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ px_ipc_name. Π€Π»Π°Π³ O_EXCL ΠΌΡ‹ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ, для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ сСмафора ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ. Если послС ΠΏΡ€Π΅ΠΆΠ΄Π΅Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ запуска ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ Π½Π΅ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Π΅ сСмафоры, ΠΌΡ‹ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π΅ΠΌ эту ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ, Π²Ρ‹Π·Π²Π°Π² ΠΏΠ΅Ρ€Π΅Π΄ ΠΈΡ… созданиСм sem_unlink ΠΈ игнорируя ошибки. ΠœΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ошибки EEXIST ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ sem_open с Ρ„Π»Π°Π³ΠΎΠΌ O_EXCL, Π° Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ sem_unlink ΠΈ Π΅Ρ‰Π΅ Ρ€Π°Π· sem_open, Π½ΠΎ это услоТнило Π±Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. Если Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π·Π°ΠΏΡƒΡ‰Π΅Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ экзСмпляр ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ (Ρ‡Ρ‚ΠΎ слСдуСт ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄ созданиСм сСмафоров), ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ ΠΊ Ρ€Π°Π·Π΄Π΅Π»Ρƒ 9.7, Π³Π΄Π΅ описаны ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой Π·Π°Π΄Π°Ρ‡ΠΈ.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π΄Π²ΡƒΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

26-29 Π‘ΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Π΄Π²Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… являСтся ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΌ, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ β€” ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ. ΠŸΡ€ΠΈ запускС Π½ΠΈΠΊΠ°ΠΊΠΈΠ΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΈΠΌ Π½Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ.

30-36 Π“Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΆΠ΄Π΅Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ производитСля ΠΈ потрСбитСля, Π° Π·Π°Ρ‚Π΅ΠΌ удаляСт Ρ‚Ρ€ΠΈ сСмафора.

ΠŸΠ Π˜ΠœΠ•Π§ΠΠΠ˜Π•

ΠœΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ сСмафора sem_close, Π½ΠΎ это дСлаСтся автоматичСски ΠΏΡ€ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ процСсса. А Π²ΠΎΡ‚ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ имя сСмафора ΠΈΠ· Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмы Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ явно.

Π’ листингС 10.9 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ produce ΠΈ consume.

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

//pxsem/prodcons1.c

39 void *

40 produce(void *arg)

41 {

42  int i;

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

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

45   Sem_wait(shared.mutex);

46   shared.buff[i % NBUFF] = i; /* ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ i Π² цикличСский Π±ΡƒΡ„Π΅Ρ€ */

47   Sem_post(shared.mutex);

48   Sem_post(shared.nstored); /* сохраняСм Π΅Ρ‰Π΅ 1 элСмСнт */

49  }

50  return(NULL);

51 }


52 void *

53 consume(void *arg)

54 {

55  int i;

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

57   Sem_wait(shared.nstored); /* ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ появлСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² Π±ΡƒΡ„Π΅Ρ€Π΅ */

58   Sem_wait(shared.mutex);

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

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

61   Sem_post(shared.mutex);

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

63  }

64  return(NULL);

65 }

ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ освобоТдСния мСста Π² Π±ΡƒΡ„Π΅Ρ€Π΅

44 ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ sem_wait для сСмафора nempty, оТидая появлСния свободного мСста. Π’ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ этой ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сСмафора nempty ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡΡ с NBUFF Π΄ΠΎ NBUFF-1.

ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ элСмСнт Π² Π±ΡƒΡ„Π΅Ρ€

45-48 ΠŸΠ΅Ρ€Π΅Π΄ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ΠΌ Π½ΠΎΠ²ΠΎΠ³ΠΎ элСмСнта Π² Π±ΡƒΡ„Π΅Ρ€ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ Π½Π° сСмафор mutex. Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, Π³Π΄Π΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ просто сохраняСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² элСмСнтС массива с индСксом i % NBUFF, для описания состояния Π±ΡƒΡ„Π΅Ρ€Π° Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… раздСляСмых ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΌΡ‹ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ связный список, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½ΡƒΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ элСмСнта Π² Π±ΡƒΡ„Π΅Ρ€). Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, установка ΠΈ снятиС сСмафора mutex Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ ΠΌΡ‹ ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ эту Ρ‚Π΅Ρ…Π½ΠΈΠΊΡƒ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π΅Π΅ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ являСтся Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΌ Π² Π·Π°Π΄Π°Ρ‡Π°Ρ… Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ€ΠΎΠ΄Π° (ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π±ΡƒΡ„Π΅Ρ€Π°, раздСляСмого нСсколькими ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ).

ПослС помСщСния элСмСнта Π² Π±ΡƒΡ„Π΅Ρ€ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° с сСмафора mutex снимаСтся (Π΅Π³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ увСличиваСтся с 0 Π΄ΠΎ 1) ΠΈ увСличиваСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сСмафора nstored. ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ этой ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ nstored измСнится с Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ значСния 0 Π΄ΠΎ 1.