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

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

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

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

Π‘ этой Π·Π°Π΄Π°Ρ‡Π΅ΠΉ ΠΌΡ‹ рСгулярно сталкиваСмся ΠΏΡ€ΠΈ использовании ΠΊΠ°Π½Π°Π»ΠΎΠ² Unix. Команда ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π°Ρ ΠΊΠ°Π½Π°Π»

grep pattern chapters.* | wc -l

являСтся ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ Ρ‚Π°ΠΊΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΈ. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° grep выступаСт ΠΊΠ°ΠΊ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ (СдинствСнный), a wc β€” ΠΊΠ°ΠΊ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ (Ρ‚ΠΎΠΆΠ΅ СдинствСнный). Канал ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΠ°ΠΊ Ρ„ΠΎΡ€ΠΌΠ° IPC. ВрСбуСмая синхронизация ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΌ ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ обСспСчиваСтся ядром, ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ write производитСля ΠΈ read покупатСля. Если ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ ΠΎΠΏΠ΅Ρ€Π΅ΠΆΠ°Π΅Ρ‚ потрСбитСля (ΠΊΠ°Π½Π°Π» пСрСполняСтся), ядро приостанавливаСт производитСля ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ write, ΠΏΠΎΠΊΠ° Π² ΠΊΠ°Π½Π°Π»Π΅ Π½Π΅ появится мСсто. Если ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ ΠΎΠΏΠ΅Ρ€Π΅ΠΆΠ°Π΅Ρ‚ производитСля (ΠΊΠ°Π½Π°Π» ΠΎΠΏΡƒΡΡ‚ΠΎΡˆΠ°Π΅Ρ‚ΡΡ), ядро приостанавливаСт потрСбитСля ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ read, ΠΏΠΎΠΊΠ° Π² ΠΊΠ°Π½Π°Π»Π΅ Π½Π΅ появятся Π΄Π°Π½Π½Ρ‹Π΅.

Π’Π°ΠΊΠΎΠΉ Ρ‚ΠΈΠΏ синхронизации называСтся нСявным; ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π½Π΅ Π·Π½Π°ΡŽΡ‚ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ синхронизация Π²ΠΎΠΎΠ±Ρ‰Π΅ осущСствляСтся. Если Π±Ρ‹ ΠΌΡ‹ использовали ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ сообщСний Posix ΠΈΠ»ΠΈ System V Π² качСствС срСдства IPC ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΌ ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ, ядро снова взяло Π±Ρ‹ Π½Π° сСбя обСспСчСниС синхронизации.

ΠŸΡ€ΠΈ использовании раздСляСмой памяти ΠΊΠ°ΠΊ срСдства IPC производитСля ΠΈ потрСбитСля, ΠΎΠ΄Π½Π°ΠΊΠΎ, трСбуСтся использованиС ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ Π²ΠΈΠ΄Π° явной синхронизации. ΠœΡ‹ продСмонстрируСм это Π½Π° использовании Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ. Π‘Ρ…Π΅ΠΌΠ° рассматриваСмого ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Π° Π½Π° рис. 7.1.

Π’ ΠΎΠ΄Π½ΠΎΠΌ процСссС Ρƒ нас имССтся нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ. ЦСлочислСнный массив buff содСрТит ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΈ потрСбляСмыС Π΄Π°Π½Π½Ρ‹Π΅ (Π΄Π°Π½Π½Ρ‹Π΅ совмСстного пользования). Для простоты ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΠΈ просто ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ buff[0] Π² 0, buff [1] Π² 1 ΠΈ Ρ‚.Π΄. ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ ΠΏΠ΅Ρ€Π΅Π±ΠΈΡ€Π°Π΅Ρ‚ элСмСнты массива, провСряя ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΡŒ записСй.

Π’ этом ΠΏΠ΅Ρ€Π²ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ ΠΊΠΎΠ½Ρ†Π΅Π½Ρ‚Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° синхронизации ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ-производитСлями. ΠŸΠΎΡ‚ΠΎΠΊ-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΏΡƒΡ‰Π΅Π½, ΠΏΠΎΠΊΠ° всС ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΠΈ Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Ρ‚ свою Ρ€Π°Π±ΠΎΡ‚Ρƒ. Π’ листингС 7.1 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° функция main нашСго ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°.

Рис. 7.1. ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΠΈ ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ


Листинг 7.1.[1] Ѐункция main

//mutex/prodcons2.с

1  #include "unpipc.h"

2  #define MAXNITEMS 1000000

3  #define MAXNTHREADS 100

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


5  struct {

6   pthread_mutex_t mutex;

7   int buff[MAXNITEMS];

8   int nput;

9   int nval;

10 } shared = {

11  PTHREAD_MUTEX_INITIALIZER

12 };


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


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: prodcons2 <#items> <#threads>");

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

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

23  Set_concurrency(nthreads);

24  /* запуск всСх ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ */

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

26   count[i] = 0;

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

28  }

29  /* ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ всСх ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ */

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

31   Pthread_join(tid_produce[i], NULL);

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

33  }

34  /* запуск ΠΈ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠ°-потрСбитСля */

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

36  Pthread_join(tid_consume, NULL);

37  exit(0);

38 }

БовмСстноС использованиС Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ

4-12 Π­Ρ‚ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. ΠœΡ‹ объСдиняСм ΠΈΡ… Π² структуру с ΠΈΠΌΠ΅Π½Π΅ΠΌ shared вмСстС с Π²Π·Π°ΠΈΠΌΠ½Ρ‹ΠΌ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ΄Ρ‡Π΅Ρ€ΠΊΠ½ΡƒΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ доступ ΠΊ Π½ΠΈΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ вмСстС с Π½ΠΈΠΌ. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ nput Ρ…Ρ€Π°Π½ΠΈΡ‚ индСкс ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ элСмСнта массива buff, ΠΏΠΎΠ΄Π»Π΅ΠΆΠ°Ρ‰Π΅Π³ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅, a nval содСрТит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π² Π½Π΅Π³ΠΎ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΎ (0, 1, 2 ΠΈ Ρ‚.Π΄.). ΠœΡ‹ выдСляСм ΠΏΠ°ΠΌΡΡ‚ΡŒ ΠΏΠΎΠ΄ эту структуру ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ΅ для синхронизации ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ.

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

ΠœΡ‹ всСгда Π±ΡƒΠ΄Π΅ΠΌ ΡΡ‚Π°Ρ€Π°Ρ‚ΡŒΡΡ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ вмСстС со срСдствами синхронизации, ΠΊ Π½ΠΈΠΌ относящимися (Π²Π·Π°ΠΈΠΌΠ½Ρ‹ΠΌΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌΠΈ, условными ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ, сСмафорами), Π² ΠΎΠ΄Π½ΠΎΠΉ структурС, ΠΊΠ°ΠΊ ΠΌΡ‹ сдСлали Π² этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅. Π­Ρ‚ΠΎ Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΉ ΡΡ‚ΠΈΠ»ΡŒ программирования. Однако Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… случаях совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ динамичСскими, прСдставляя собой, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, связный список. ΠœΡ‹, Π½Π°Π²Π΅Ρ€Π½ΠΎΠ΅, смоТСм ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π² структуру ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ элСмСнт списка вмСстС со срСдствами синхронизации (ΠΊΠ°ΠΊ Π² структурС mq_hdr Π² листингС 5.16), Π½ΠΎ ΠΎΡΡ‚Π°Π²ΡˆΠ°ΡΡΡ Ρ‡Π°ΡΡ‚ΡŒ списка Π² структуру Π½Π΅ ΠΏΠΎΠΏΠ°Π΄Π΅Ρ‚. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, это Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π½Π΅ всСгда являСтся ΠΈΠ΄Π΅Π°Π»ΡŒΠ½Ρ‹ΠΌ.

АргумСнты ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки

19-22 ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ количСство элСмСнтов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½Ρ‹ производитСлями, Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ β€” количСство запускаСмых ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ.

Установка уровня ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ

23 Ѐункция set_concurrency (наша собствСнная) ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ подсистСмС ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² количСство ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ выполняСмых ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². Π’ Solaris 2.6 ΠΎΠ½Π° просто Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ thr_setconcurrency, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ Π΅Π΅ запуск Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ, Ссли ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρƒ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… процСссов-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ Π±Ρ‹Π»Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π½Π°Ρ‡Π°Ρ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ. Если ΠΌΡ‹ Π½Π΅ сдСлаСм этого Π²Ρ‹Π·ΠΎΠ²Π° Π² систСмС Solaris, Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΏΡƒΡ‰Π΅Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ. Π’ Digital Unix 4.0B наша функция set_concurrency Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ‚ Π½ΠΈΡ‡Π΅Π³ΠΎ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² этой систСмС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ всС ΠΏΠΎΡ‚ΠΎΠΊΠΈ процСсса ΠΈΠΌΠ΅ΡŽΡ‚ Ρ€Π°Π²Π½Ρ‹Π΅ ΠΏΡ€Π°Π²Π° Π½Π° Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ рСсурсы.

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

Unix 98 Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ наличия Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_setconcurrency, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰Π΅ΠΉ это ΠΆΠ΅ дСйствиС. Π­Ρ‚Π° функция трСбуСтся для Ρ‚Π΅Ρ… Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π΅ΠΊΡΠΈΡ€ΡƒΡŽΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ (создаваСмыС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ pthread_create) Π½Π° нСбольшоС мноТСство выполняСмых ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ядра. Π’Π°ΠΊΠΈΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ часто Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ Β«ΠΌΠ½ΠΎΠ³ΠΈΠ΅-ΠΊ-Π½Π΅ΠΌΠ½ΠΎΠ³ΠΈΠΌΒ» (many-to-few), Β«Π΄Π²ΡƒΡ…ΡƒΡ€ΠΎΠ²Π½Π΅Π²Ρ‹Π΅Β» (two-level) ΠΈΠ»ΠΈ «М-Π½Π°-NΒ» (M-to-N). Π’ Ρ€Π°Π·Π΄Π΅Π»Π΅ 5.6 ΠΊΠ½ΠΈΠ³ΠΈ [3] ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ ядра Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ процСссов-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ

24-28 Π‘ΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ ΠΏΠΎΡ‚ΠΎΠΊΠΈ-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΠΈ, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ produce. Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² хранятся Π² массивС tid_produce. АргумСнтом ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°-производитСля являСтся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° элСмСнт массива count. Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ 0, ΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ своСго счСтчика Π½Π° 1 ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ элСмСнта Π² Π±ΡƒΡ„Π΅Ρ€. Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΠΌΠΎΠ΅ массива счСтчиков Π·Π°Ρ‚Π΅ΠΌ выводится Π½Π° экран, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡƒΠ·Π½Π°Ρ‚ΡŒ, сколько элСмСнтов Π±Ρ‹Π»ΠΎ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΎ Π² Π±ΡƒΡ„Π΅Ρ€ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ².

ОТиданиС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ, запуск потрСбитСля

29-36 ΠœΡ‹ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ всСх ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²-ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ, выводя содСрТимоС счСтчика для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°, Π° Π·Π°Ρ‚Π΅ΠΌ запускаСм СдинствСнный процСсс-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ (Π½Π° Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚) ΠΌΡ‹ ΠΈΡΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ синхронизации ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ ΠΈ производитСлями. ΠœΡ‹ ΠΆΠ΄Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ потрСбитСля, Π° Π·Π°Ρ‚Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅ΠΌ Ρ€Π°Π±ΠΎΡ‚Ρƒ процСсса. Π’ листингС 7.2 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ produce ΠΈ consume.

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

//mutex/prodcons2.с

39 void *

40 produce(void *arg)

41 {

42  for (;;) {

43   Pthread_mutex_lock(&shared.mutex);

44   if (shared.nput >= nitems) {

45    Pthread_mutex_unlock(&shared.mutex);

46    return(NULL); /* массив ΠΏΠΎΠ»Π½Ρ‹ΠΉ, Π³ΠΎΡ‚ΠΎΠ²ΠΎ */

47   }

48   shared.buff[shared.nput] = shared.nval;

49   shared.nput++;

50   shared.nval++;

51   Pthread_mutex_unlock(&shared.mutex);

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

53  }

54 }


55 void *

56 consume(void *arg)

57 {

58  int i;

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

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

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

62  }

63  return(NULL);

64 }

Π€ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…

42-53 ΠšΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΠ°Ρ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ ΠΊΠΎΠ΄Π° производитСля состоит ΠΈΠ· ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π½Π° достиТСниС ΠΊΠΎΠ½Ρ†Π° массива (Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹)

if (shared.nput >= nitems)

ΠΈ Ρ‚Ρ€Π΅Ρ… строк, ΠΏΠΎΠΌΠ΅Ρ‰Π°ΡŽΡ‰ΠΈΡ… ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² массив:

shared.buff[shared.nput] = shared.nval;

shared.nput++;

shared.nval++;

ΠœΡ‹ Π·Π°Ρ‰ΠΈΡ‰Π°Π΅ΠΌ эту ΠΎΠ±Π»Π°ΡΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, Π½Π΅ Π·Π°Π±Ρ‹Π² Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ послС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ элСмСнта count (Ρ‡Π΅Ρ€Π΅Π· ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ arg) Π½Π΅ относится ΠΊ критичСской области, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρƒ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° счСтчик свой (массив count Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main). ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΌΡ‹ Π½Π΅ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ эту строку Π² Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΡƒΡŽ Π²Π·Π°ΠΈΠΌΠ½Ρ‹ΠΌ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ. Один ΠΈΠ· ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΎΠ² Ρ…ΠΎΡ€ΠΎΡˆΠ΅Π³ΠΎ стиля программирования Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ объСма ΠΊΠΎΠ΄Π°, Π·Π°Ρ‰ΠΈΡ‰Π°Π΅ΠΌΠΎΠ³ΠΎ Π²Π·Π°ΠΈΠΌΠ½Ρ‹ΠΌ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ.