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

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

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

30.11. Π‘Π΅Ρ€Π²Π΅Ρ€ TCP с ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ accept

Π Π°Π½Π΅Π΅ Π² этой Π³Π»Π°Π²Π΅ ΠΌΡ‹ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ»ΠΈ, Ρ‡Ρ‚ΠΎ вСрсии, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π·Π°Ρ€Π°Π½Π΅Π΅ создаСтся ΠΏΡƒΠ» Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… процСссов, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ быстрСС, Ρ‡Π΅ΠΌ Ρ‚Π΅, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ клиСнтского запроса приходится Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ fork. Для систСм, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΈ, Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ имССтся Ρ‚Π° ΠΆΠ΅ Π·Π°ΠΊΠΎΠ½ΠΎΠΌΠ΅Ρ€Π½ΠΎΡΡ‚ΡŒ: быстрСС сразу ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΡƒΠ» ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΏΡ€ΠΈ запускС сСрвСра, Ρ‡Π΅ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ поступлСния запросов ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ². Основная идСя Ρ‚Π°ΠΊΠΎΠ³ΠΎ сСрвСра Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΡƒΠ» ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Π·Π°Ρ‚Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ accept. ВмСсто Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΈ Π² Π²Ρ‹Π·ΠΎΠ²Π΅ accept, ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, ΠΊΠ°ΠΊ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 30.8. Π­Ρ‚ΠΎ позволяСт Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ accept Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ Π² ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ Ρ„Π°ΠΉΠ»Π° для Π·Π°Ρ‰ΠΈΡ‚Ρ‹ accept Π² Ρ‚Π°ΠΊΠΎΠΌ случаС бСссмыслСнно, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΡ€ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π²Π½ΡƒΡ‚Ρ€ΠΈ Π΄Π°Π½Π½ΠΎΠ³ΠΎ процСсса ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.

Π’ листингС 30.21 ΠΏΠΎΠΊΠ°Π·Π°Π½ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» pthread07.h, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠΉ структуру Thread, ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‰ΡƒΡŽ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅.

Листинг 30.21. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» pthread07.h

//server/pthread07.h

1 typedef struct {

2  pthread_t thread_tid; /* ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΏΠΎΡ‚ΠΎΠΊΠ° */

3  long thread_count; /* количСство ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Ρ… запросов */

4 } Thread;

5 Thread *tptr; /* массив структур Thread */


6 int listenfd, nthreads;

7 socklen_t addrlen;

8 pthread_mutex_t mlock;

ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ объявляСм нСсколько Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ дСскриптор ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ сокСта ΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ всСми ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ.

Π’ листингС 30.22 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° функция main.

Листинг 30.22. Ѐункция main для сСрвСра TCP с ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

//server/serv07.c

 1 #include "unpthread.h"

 2 #include "pthread07.h"


 3 pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;


 4 int

 5 main(int argc, char **argv)

 6 {

 7  int i;

 8  void sig_int(int), thread_make(int);


 9  if (argc == 3)

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

11  else if (argc == 4)

12   listenfd = Tcp_1isten(argv[1], argv[2], &addrlen);

13  else

14   err_quit("usage: serv07 [ <host> ] <port#> <#threads>");

15  nthreads = atoi(argv[argc - 1]);

16  tptr = Calloc(nthreads, sizeof(Thread));


17  for (i = 0; i < nthreads; i++)

18  thread_make(i); /* Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ основной ΠΏΠΎΡ‚ΠΎΠΊ */


19  Signal(SIGINT, sig_int);


20  for (;;)

21   pause(); /* ΠΏΠΎΡ‚ΠΎΠΊΠΈ всС Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΠ»ΠΈ */

22 }

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ thread_make ΠΈ thread_main ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ Π² листингС 30.23.

Листинг 30.23. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ thread_make ΠΈ thread_main

//server/pthread07.c

 1 #include "unpthread.h"

 2 #include "pthread07.h"


 3 void

 4 thread_make(int i)

 5 {

 6  void *thread_main(void*);


 7  Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void*)i);

 8  return; /* Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ основной ΠΏΠΎΡ‚ΠΎΠΊ */

 9 }


10 void*

11 thread_main(void *arg)

12 {

13  int connfd;

14  void web_child(int);

15  socklen_t clilen;

16  struct sockaddr *cliaddr;


17  cliaddr = Malloc(addrlen);


18  printf("thread %d starting\n", (int)arg);

19  for (;;) {

20   clilen = addrlen;

21   Pthread_mutex_lock(&mlock);

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

23   Pthread_mutex_unlock(&mlock);

24   tptr[(int)arg].thread_count++;


25   web_child(connfd); /* ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° запроса */

26   Close(connfd);

27  }

28 }

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

7 Π‘ΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… выполняСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_main. ЕдинствСнным Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ являСтся порядковый Π½ΠΎΠΌΠ΅Ρ€ ΠΏΠΎΡ‚ΠΎΠΊΠ°.

21-23 Π€ΡƒΠ½ΠΊΡ†ΠΈΡ thread_main Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_mutex_lock ΠΈ pthread_mutex_unlock соотвСтствСнно Π΄ΠΎ ΠΈ послС Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept.

Бравнивая строки 6 ΠΈ 7 Π² Ρ‚Π°Π±Π». 30.1, ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ эта послСдняя вСрсия нашСго сСрвСра быстрСС, Ρ‡Π΅ΠΌ вСрсия с созданиСм Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ клиСнтского запроса. Π­Ρ‚ΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π² Π΄Π°Π½Π½ΠΎΠΉ вСрсии ΠΌΡ‹ сразу создаСм ΠΏΡƒΠ» ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΈ Π½Π΅ Ρ‚Ρ€Π°Ρ‚ΠΈΠΌ врСмя Π½Π° созданиС Π½ΠΎΠ²Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ поступлСния клиСнтских запросов. На самом Π΄Π΅Π»Π΅ эта вСрсия сСрвСра β€” самая Π±Ρ‹ΡΡ‚Ρ€ΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ для всСх ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… систСм, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ испытывали.

Π’ Ρ‚Π°Π±Π». 30.2 ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ распрСдСлСниС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ счСтчика thread_count структуры Thread, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигнала SIGINT ΠΏΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ сСрвСра. Π Π°Π²Π½ΠΎΠΌΠ΅Ρ€Π½ΠΎΡΡ‚ΡŒ этого распрСдСлСния ΠΎΠ±ΡŠΡΡΠ½ΡΠ΅Ρ‚ΡΡ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ Π²Ρ‹Π±ΠΎΡ€Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ планирования Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π±ΠΈΡ€Π°Π΅Ρ‚ всС ΠΏΠΎΡ‚ΠΎΠΊΠΈ Π² Ρ†ΠΈΠΊΠ»Π΅.

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

Π’ Π‘Π΅Ρ€ΠΊΠ»ΠΈ-ядрах Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½Π° Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΅Ρ€ΡΠΈΡŽ, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»Π΅Π½Π½ΡƒΡŽ Π² листингС 30.23, Π±Π΅Π· Π²Π·Π°ΠΈΠΌΠ½Ρ‹Ρ… ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ. Но Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ этого врСмя, Π·Π°Ρ‚Ρ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌΠΎΠ΅ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΡŒΠ½Ρ‹ΠΌ процСссором, увСличится. Если Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π΄Π²Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°, ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… складываСтся врСмя Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ процСссора β€” ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ΅ ΠΈ систСмноС врСмя β€” Ρ‚ΠΎ окаТСтся, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ΡΡ ΠΏΡ€ΠΈ отсутствии Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ (ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ осущСствляСтся Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², входящСй Π² ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ΅ пространство), Π½ΠΎ систСмноС врСмя возрастаСт (Π·Π° счСт эффСкта Β«ΠΎΠ±Ρ‰Π΅ΠΉ ΠΏΠΎΠ±ΡƒΠ΄ΠΊΠΈΒ», Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰Π΅Π³ΠΎ, ΠΊΠΎΠ³Π΄Π° всС ΠΏΠΎΡ‚ΠΎΠΊΠΈ, Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π² Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept, выходят ΠΈΠ· состояния оТидания ΠΏΡ€ΠΈ появлСнии Π½ΠΎΠ²ΠΎΠ³ΠΎ клиСнтского соСдинСния). Для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ соСдинСниС ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π»ΠΎΡΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠ° нСкая Ρ€Π°Π·Π½ΠΎΠ²ΠΈΠ΄Π½ΠΎΡΡ‚ΡŒ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, ΠΈ оказываСтся, Ρ‡Ρ‚ΠΎ быстрСС это Π΄Π΅Π»Π°ΡŽΡ‚ сами ΠΏΠΎΡ‚ΠΎΠΊΠΈ, Π° Π½Π΅ ядро.

30.12. Π‘Π΅Ρ€Π²Π΅Ρ€ с ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²: основной ΠΏΠΎΡ‚ΠΎΠΊ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ accept

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

ΠŸΡ€ΠΈ Ρ‚Π°ΠΊΠΎΠΌ устройствС сСрвСра Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠΌ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Π΄ΠΎΠ»ΠΆΠ½Π° ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒΡΡ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° присоСдинСнного дСскриптора ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π² ΠΏΡƒΠ»Π΅. БущСствуСт нСсколько способов Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой Π·Π°Π΄Π°Ρ‡ΠΈ. МоТно, ΠΊΠ°ΠΊ ΠΈ ΠΏΡ€Π΅ΠΆΠ΄Π΅, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρƒ дСскриптора, Π½ΠΎ ΠΏΡ€ΠΈ этом Π½Π΅ трСбуСтся ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ дСскриптор ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ всС ΠΎΠ½ΠΈ, Π² Ρ‚ΠΎΠΌ числС ΠΈ Π³Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‚ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΈ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ процСссу. ВсС, Ρ‡Ρ‚ΠΎ трСбуСтся Π·Π½Π°Ρ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ, ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰Π΅ΠΌΡƒ дСскриптор, β€” это Π½ΠΎΠΌΠ΅Ρ€ дСскриптора. Π’ листингС 30.24 ΠΏΠΎΠΊΠ°Π·Π°Π½ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» pthread08.h, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠΉ структуру Thread, Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ»Ρƒ, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ Π² листингС 30.21.

Листинг 30.24. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» pthread08.h

//server/pthread08.h

 1 typedef struct {

 2  pthread_t thread_tid; /* ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΏΠΎΡ‚ΠΎΠΊΠ° */

 3  long thread_count; /* количСство ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Ρ… запросов */

 4 } Thread;

 5 Thread *tptr; /* массив структур Thread */


 6 #define MAXNCLI 32

 7 int clifd[MAXNCLI], iget, iput;

 8 pthread_mutex_t clifd_mutex;

 9 pthread_cond_t clifd_cond;

ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ массива для записи дСскрипторов присоСдинСнных сокСтов

6-9 ΠœΡ‹ опрСдСляСм массив clifd, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π³Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ записываСт дСскрипторы присоСдинСнных сокСтов. Π‘Π²ΠΎΠ±ΠΎΠ΄Π½Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΈΠ· ΠΏΡƒΠ»Π° ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ дСскриптору ΠΈΠ· этого массива ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ запрос, iput β€” это индСкс Π² Π΄Π°Π½Π½ΠΎΠΌ массивС для ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ элСмСнта, записываСмого Π² Π½Π΅Π³ΠΎ Π³Π»Π°Π²Π½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ, a iget β€” это индСкс ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ элСмСнта массива, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠ³ΠΎ свободному ΠΏΠΎΡ‚ΠΎΠΊΡƒ для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ. РазумССтся, эта структура Π΄Π°Π½Π½Ρ‹Ρ…, совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠ°Ρ всСми ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ, Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π°, ΠΈ поэтому ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΡƒΡΠ»ΠΎΠ²Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.

Π’ листингС 30.25 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° функция main.

Листинг 30.25. Ѐункция main для сСрвСра с ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

//server/serv08.c

 1 #include "unpthread.h"

 2 #include "pthread08.h"


 3 static int nthreads;

 4 pthread_mutex_t clifd_mutex = PTHREAD_MUTEX_INITIALIZER;

 5 pthread_cond_t clifd_cond = PTHREAD_COND_INITIALIZER;


 6 int

 7 main(int argc, char **argv)

 8 {

 9  int i, listenfd, connfd;

10  void sig_int(int), thread_make(int);

11  socklen_t addrlen, clilen;

12  struct sockaddr *cliaddr;