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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX: Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° сСтСвых ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 233

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

Π’ листингС 30.15 ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ my_lock_wait ΠΈ my_lock_release. Они содСрТат Π²Ρ‹Π·ΠΎΠ²Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Pthreads, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹Ρ… для блокирования ΠΈ разблокирования Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ.

Листинг 30.15. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ my_lock_wait ΠΈ my_lock_release: использованиС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ Pthread

//server/lock_pthread.c

17 void

18 my_lock_wait()

19 {

20  Pthread_mutex_lock(mptr),

21 }


22 void

23 my_lock_release()

24 {

25  Pthread_mutex_unlock(mptr);

26 }

Бравнивая строки 3 ΠΈ 4 Ρ‚Π°Π±Π». 30.1, ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ вСрсия, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π°Ρ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ процСссов ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, характСризуСтся Π±ΠΎΠ»Π΅Π΅ высоким быстродСйствиСм, Ρ‡Π΅ΠΌ вСрсия с Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΎΠΉ Ρ„Π°ΠΉΠ»Π°.

30.9. Π‘Π΅Ρ€Π²Π΅Ρ€ TCP с ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ процСссов: ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° дСскриптора

ПослСднСй ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠ΅ΠΉ нашСго сСрвСра с ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ процСссов являСтся вСрсия, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ accept, Π° Π·Π°Ρ‚Π΅ΠΌ Β«ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚Β» присоСдинСнный сокСт ΠΊΠ°ΠΊΠΎΠΌΡƒ-Π»ΠΈΠ±ΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅ΠΌΡƒ процСссу. Π­Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΎΠ±ΠΎΠΉΡ‚ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ Π²Ρ‹Π·ΠΎΠ²Π° accept, Π½ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ способа ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ дСскриптора ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΌ ΠΈ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌ процСссами. Π­Ρ‚Π° Ρ‚Π΅Ρ…Π½ΠΈΠΊΠ° Ρ‚Π°ΠΊΠΆΠ΅ нСсколько услоТняСт ΠΊΠΎΠ΄, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠΌΡƒ процСссу приходится ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΈΠ· Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… процСссов заняты, Π° ΠΊΠ°ΠΊΠΈΠ΅ свободны, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ дСскриптор Ρ‚ΠΎΠ»ΡŒΠΊΠΎ свободным Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌ процСссам.

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

Π’ Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅Π³ΠΎ процСсса Π½Π°ΠΌ Π½ΡƒΠΆΠ½Π° нСкая структура, содСрТащая ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Π½Π΅ΠΌ. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» child.h, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ опрСдСляСтся структура Child, ΠΏΠΎΠΊΠ°Π·Π°Π½ Π² листингС 30.16.

Листинг 30.16. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° Child

//server/child.h

1 typedef struct {

2  pid_t child_pid;  /* ID процСсса */

3  int child_pipefd; /* ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ (Π½Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ) ΠΊΠ°Π½Π°Π» ΠΌΠ΅ΠΆΠ΄Ρƒ

                        Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΌ ΠΈ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌ процСссами */

4  int child_status; /* 0 = Π³ΠΎΡ‚ΠΎΠ²ΠΎ */

5  long child_count; /* количСство ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌΡ‹Ρ… соСдинСний */

6 } Child;


7 Child *cptr; /* массив структур Child */

ΠœΡ‹ записываСм ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅Π³ΠΎ процСсса, дСскриптор ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠ°Π½Π°Π»Π° (pipe) Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ процСсса, связанного с Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌ, статус Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅Π³ΠΎ процСсса ΠΈ количСство ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌΡ‹Ρ… Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌ процСссом клиСнтских соСдинСний. Π­Ρ‚ΠΎ количСство выводится ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ сигнала SIGINT ΠΈ позволяСт Π½Π°ΠΌ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ распрСдСлСниС клиСнтских запросов ΠΌΠ΅ΠΆΠ΄Ρƒ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌΠΈ процСссами.

Рассмотрим сначала Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ child_make, которая ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² листингС 30.17. ΠœΡ‹ создаСм ΠΊΠ°Π½Π°Π» ΠΈ Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹ΠΉ сокСт Unix (см. Π³Π»Π°Π²Ρƒ 14) ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fork. ПослС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ создан Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс, Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ дСскриптор (sockfd[1]), Π° Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΠΎΠΉ дСскриптор (sockfd[0]). Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ свой дСскриптор ΠΊΠ°Π½Π°Π»Π° (sockfd[1]) ΠΊ стандартному ΠΏΠΎΡ‚ΠΎΠΊΡƒ сообщСний ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ…, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ это устройство для связи с Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΌ процСссом. Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ ΠΏΡ€ΠΎΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Π½ схСмой, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΉ Π½Π° рис. 30.3.

Листинг 30.17. Ѐункция child_make: ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° дСскриптора Π² сСрвСрС с ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… процСссов

//server/child05.c

 1 #include "unp.h"

 2 #include "child.h"


 3 pid_t

 4 child_make(int i, int listenfd, int addrlen)

 5 {

 6  int sockfd[2];

 7  pid_t pid;

 8  void child_main(int, int, int);


 9  Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);


10  if ((pid = Fork()) > 0) {

11   Close(sockfd[1]);

12   cptr[i].child_pid = pid;

13   cptr[i].child_pipefd = sockfd[0];

14   cptr[i].child_status = 0;

15   return (pid); /* Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс */

16  }

17  Dup2(sockfd[1], STDERR_FILENO); /* ΠΊΠ°Π½Π°Π» ΠΎΡ‚ Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅Π³ΠΎ процСсса ΠΊ

                                       Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠΌΡƒ */

18  Close(sockfd[0]);

19  Close(sockfd[1]);

20  Close(listenfd); /* Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅ΠΌΡƒ процСссу Π½Π΅ трСбуСтся, Ρ‡Ρ‚ΠΎΠ±Ρ‹

                        ΠΎΠ½ Π±Ρ‹Π» ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ */

21  child_main(i, listenfd, addrlen); /* Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ */

22 }

Рис. 30.3. Канал послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ ΠΈ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс Π·Π°ΠΊΡ€Ρ‹Π»ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΊΠΎΠ½Π΅Ρ†

ПослС создания всСх Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… процСссов ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ схСму, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΡƒΡŽ Π½Π° рис. 30.4. ΠœΡ‹ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ сокСт Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅ΠΌ процСссС, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ accept. ΠœΡ‹ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π½Π° рисункС, Ρ‡Ρ‚ΠΎ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ сокСт, Π° Ρ‚Π°ΠΊΠΆΠ΅ всС Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹Π΅ сокСты. Как ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ³Π°Π΄Π°Ρ‚ΡŒΡΡ, Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ select для ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π΅ΠΊΡΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ всСх дСскрипторов.

Рис. 30.4. ΠšΠ°Π½Π°Π»Ρ‹ послС создания всСх Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… процСссов

Π’ листингС 30.18 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° функция main. Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… вСрсий этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π² Π΄Π°Π½Π½ΠΎΠΌ случаС Π² памяти Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ всС Π½Π°Π±ΠΎΡ€Ρ‹ дСскрипторов ΠΈ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π½Π°Π±ΠΎΡ€Π΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ всС Π±ΠΈΡ‚Ρ‹, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΠΎΠΌΡƒ сокСту ΠΈ ΠΊΠ°Π½Π°Π»Ρƒ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅Π³ΠΎ процСсса. ВычисляСтся Ρ‚Π°ΠΊΠΆΠ΅ максимальноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ дСскриптора ΠΈ выдСляСтся ΠΏΠ°ΠΌΡΡ‚ΡŒ для массива структур Child. Основной Ρ†ΠΈΠΊΠ» запускаСтся ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ select.

Листинг 30.18. Ѐункция main, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π°Ρ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρƒ дСскриптора

//server/serv05.c

 1 #include "unp.h"

 2 #include "child.h"


 3 static int nchildren;


 4 int

 5 main(int argc, char **argv)

 6 {

 7  int listenfd, i, navail, maxfd, nsel, connfd, rc;

 8  void sig_int(int);

 9  pid_t child_make(int, int, int);

10  ssize_t n;

11  fd_set rset, masterset;

12  socklen_t addrlen, clilen;

13  struct sockaddr *cliaddr;


14  if (argc == 3)

15   listenfd = Tcp_listen(NULL, argv[1], &addrlen);

16  else if (argc == 4)

17   listenfd = Tcp_listen(argv[1], argv[2], &addrlen);

18  else

19   err_quit("usage; serv05 [ <host> ] <port#> <#children>");


20  FD_ZERO(&masterset);

21  FD_SET(listenfd, &masterset);

22  maxfd = listenfd;

23  cliaddr = Malloc(addrlen);


24  nchildren = atoi(argv[argc - 1]);

25  navail = nchildren;

26  cptr = Calloc(nchildren, sizeof(Child));


27  /* ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ созданиС Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… процСссов */

28  for (i = 0; i < nchildren; i++) {

29   child_make(i, listenfd, addrlen); /* Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс

                                          Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ */

30   FD_SET(cptr[i].child_pipefd, &masterset);

31   maxfd = max(maxfd, cptr[i].child_pipefd);

32  }


33  Signal(SIGINT, sig_int);


34  for (;;) {

35   rset = masterset;

36   if (navail <= 0)

37    FD_CLR(listenfd, &rset); /* Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ, Ссли Π½Π΅Ρ‚ свободных

                                  Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… процСссов */

38   nsel = Select(maxfd + 1, &rset, NULL, NULL, NULL);


39   /* ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½ΠΎΠ²Ρ‹Ρ… соСдинСний */

40   if (FD_ISSET(listenfd, &rset)) {

41    clilen = addrlen;

42    connfd = Accept(listenfd, cliaddr, &clilen);


43    for (i = 0; i < nchildren; i++)

44     if (cptr[i].child_status == 0)

45      break; /* свободный */


46    if (i == nchildren)

47     err_quit("no available children");

48    cptr[i].child_status = 1; /* ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π΅ΠΌ этот Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс ΠΊΠ°ΠΊ

                                   занятый */

49    cptr[i].child_count++;

50    navail--;


51    n = Write_fd(cptr[i].child_pipefd, 1, connfd);

52    Close(connfd);

53    if (--nsel == 0)

54     continue; /* с Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°ΠΌΠΈ select() Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½ΠΎ */

55   }

56   /* поиск ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΠ²ΡˆΠΈΡ…ΡΡ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… процСссов */

57   for (i = 0; i < nchildren; i++) {

58    if (FD_ISSET(cptr[i].child_pipefd, &rset)) {

59     if ((n = Read(cptr[i].child_pipefd, &rc, 1)) == 0)

60      err_quit("child %d terminated unexpectedly", i);

61     cptr[i].child_status = 0;

62     navail++;

63     if (--nsel == 0)

64      break; /* с Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°ΠΌΠΈ select() Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½ΠΎ */

65    }

66   }

67  }

68 }