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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠžΡΠ½ΠΎΠ²Ρ‹ программирования Π² LinuxΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 169

Автор НСйл ΠœΡΡ‚ΡŒΡŽ

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π²Ρ‹ создаСтС Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ процСссы, Π½ΠΎ Π½Π΅ ΠΆΠ΄Π΅Ρ‚Π΅ ΠΈΡ… Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ, слСдуСт ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ сСрвСр ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π» сигналы SIGCHLD, прСпятствуя возникновСнию процСссов-Π·ΠΎΠΌΠ±ΠΈ.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 15.7. Π‘Π΅Ρ€Π²Π΅Ρ€ для многочислСнных ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ²

1. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° server4.c начинаСтся Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ послСдний рассмотрСнный сСрвСр с Π²Π°ΠΆΠ½Ρ‹ΠΌ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρ‹ include для Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° signal.h. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ создания ΠΈ имСнования сокСта ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ ΠΏΡ€Π΅ΠΆΠ½ΠΈΠΌΠΈ: 

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <netinet/in.h>

#include <signal.h>

#include <unistd.h>

#include <stdlib.h>


int main() {

 int server_sockfd, client_sockfd;

 int server_len, client_len;

 struct sockaddr_in server_address;

 struct sockaddr_in client_address;

 server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

 server_address.sin_family = AF_INET;

 server_address.sin_addr.s_addr = htonl(INADDR_ANY);

 server_address.sin_port = htons(9734);

 server_len = sizeof(server_address);

 bind(server_sockfd, (struct sockaddr *)&server_address, server_len);

2. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ соСдинСний, ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠΉΡ‚Π΅ подробности Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅Π³ΠΎ процСсса ΠΈ ΠΆΠ΄ΠΈΡ‚Π΅ запросов ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ²:

 listen(server_sockfd, 5);

 signal(SIGCHLD, SIG_IGN);

 while(1) {

  char ch;

  printf("server waiting\n");

3. ΠŸΡ€ΠΈΠΌΠΈΡ‚Π΅ запрос Π½Π° соСдинСниС:

  client_len = sizeof(client_address);

  client_sockfd = accept(server_sockfd,

   (struct_sockaddr*)&client_address, &client_len);

4. Π’Ρ‹Π·ΠΎΠ²ΠΈΡ‚Π΅ fork с Ρ†Π΅Π»ΡŒΡŽ создания процСсса для Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ Π²Ρ‹ ΠΈΠ»ΠΈ ΠΏΠΎΡ‚ΠΎΠΌΠΎΠΊ:

  if (fork() == 0) {

5. Π•сли Π²Ρ‹ ΠΏΠΎΡ‚ΠΎΠΌΠΎΠΊ, Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ/ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅-ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅ Π½Π° сокСтС client_sockfd. ΠŸΡΡ‚ΠΈΡΠ΅ΠΊΡƒΠ½Π΄Π½Π°Ρ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° Π½ΡƒΠΆΠ½Π° для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ это ΠΏΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ:

   read(client_sockfd, &ch, 1);

   sleep(5);

   ch++;

   write(client_sockfd, &ch, 1);

   close(client_sockfd);

   exit(0);

  }

6. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΌ ΠΈ ваша Ρ€Π°Π±ΠΎΡ‚Π° с Π΄Π°Π½Π½Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½Π°:

  else {

   close(client_socket);

  }

 }

}

Код Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΠΏΡΡ‚ΠΈΡΠ΅ΠΊΡƒΠ½Π΄Π½ΡƒΡŽ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ запроса ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° для ΠΈΠΌΠΈΡ‚Π°Ρ†ΠΈΠΈ вычислСний сСрвСра ΠΈΠ»ΠΈ обращСния ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ…. Если Π±Ρ‹ Π²Ρ‹ ΠΏΡ€ΠΎΠ΄Π΅Π»Π°Π»ΠΈ это Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ сСрвСрС, ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ client3 заняло Π±Ρ‹ ΠΏΡΡ‚ΡŒ сСкунд. Π‘ Π½ΠΎΠ²Ρ‹ΠΌ сСрвСром Π²Ρ‹ смоТСтС ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ мноТСствСнныС клиСнтскиС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ client3 ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ с ΠΎΠ±Ρ‰ΠΈΠΌ Π·Π°Ρ‚Ρ€Π°Ρ‡Π΅Π½Π½Ρ‹ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ, Ρ‡ΡƒΡ‚ΡŒ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°ΡŽΡ‰ΠΈΠΌ ΠΏΡΡ‚ΡŒ сСкунд.

$ ./server4 &

[1] 26566 server waiting

$ ./client3 & ./client3 & ./client3 & ps x

[2] 26581

[3] 26582

[4] 26583

server waiting

server waiting

server waiting

PID   TTY   STAT TIME COMMAND

26566 pts/1 S    0:00 ./server4

26581 pts/1 S    0:00 ./client3

26582 pts/1 S    0:00 ./client3

26583 pts/1 S    0:00 ./client3

26584 pts/1 R+   0:00 ps x

26585 pts/1 S    0:00 ./server4

26586 pts/1 S    0:00 ./server4

26587 pts/1 S    0:00 ./server4

$ char from server = Π’

char from server = Π’

char from server = Π’

ps x

PID  TTY    STAT TIME COMMAND

26566 pts/1 S    0:00 ./server4

26590 pts/1 R+   0:00 ps x

[2] Done   ./client3

[3]- Done  ./client3

[4]+ Done  ./client3

$

Как это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

Π’Π΅ΠΏΠ΅Ρ€ΡŒ сСрвСрная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° создаСт Π½ΠΎΠ²Ρ‹ΠΉ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, поэтому Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²ΠΈΠ΄Π΅Ρ‚ΡŒ нСсколько сообщСний ΠΎΠ± ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ сСрвСра, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ основная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ ΠΆΠ΄Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ запросы Π½Π° ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ. Π’ Π²Ρ‹Π²ΠΎΠ΄Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ps (ΠΎΡ‚Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ) ΠΏΠΎΠΊΠ°Π·Π°Π½ Π³Π»Π°Π²Π½Ρ‹ΠΉ процСсс server4 с PID, Ρ€Π°Π²Π½Ρ‹ΠΌ 26 566, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ², Π² Ρ‚ΠΎ врСмя, ΠΊΠ°ΠΊ Ρ‚Ρ€ΠΈ клиСнтских процСсса client3 ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ трСмя ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ°ΠΌΠΈ сСрвСра. ПослС пятисСкундной ΠΏΠ°ΡƒΠ·Ρ‹ всС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ свои Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‚ΡΡ. Π”ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ сСрвСрныС процСссы Ρ‚ΠΎΠΆΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‚ΡΡ, оставляя Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Π³Π»Π°Π²Π½Ρ‹ΠΉ сСрвСрный процСсс.

БСрвСрная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° примСняСт Π²Ρ‹Π·ΠΎΠ² fork для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ мноТСствСнных ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ². Π’ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ… это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ самым ΡƒΠ΄Π°Ρ‡Π½Ρ‹ΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ, Ρ‚.ΠΊ. сСрвСрная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ довольно большой, ΠΈ, ΠΊΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, сущСствуСт ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΉ ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… мноТСствСнных ΠΊΠΎΠΏΠΈΠΉ сСрвСра. На самом Π΄Π΅Π»Π΅, всС, Ρ‡Ρ‚ΠΎ Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ, β€” это способ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ мноТСствСнных ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² СдинствСнным сСрвСром Π±Π΅Π· Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΈ оТидания доставки клиСнтских запросов. РСшСниС этой Π·Π°Π΄Π°Ρ‡ΠΈ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ мноТСствСнных ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… дСскрипторов ΠΈ Π½Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ прилоТСниями с ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ сокСтов. Рассмотрим Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ select.

select

ΠžΡ‡Π΅Π½ΡŒ часто ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Linux Π²Π°ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡ‚ΡŒΡΡ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° состояния ряда Π²Π²ΠΎΠ΄ΠΎΠ² для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ ΠΏΡ€Π΅Π΄ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌΠΎΠ΅ дСйствиС. НапримСр, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, такая ΠΊΠ°ΠΊ эмулятор Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°, нуТдаСтся Π² эффСктивном способС ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ чтСния с ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Ρ‹ ΠΈ с ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡ€Ρ‚Π°. Π’ ΠΎΠ΄Π½ΠΎΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠΉ систСмС ΠΏΠΎΠ΄ΠΎΠΉΠ΄Π΅Ρ‚ Ρ†ΠΈΠΊΠ» "Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ оТидания", ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ ΠΏΡ€ΠΎΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ Π²Π²ΠΎΠ΄ Π² поискС Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ Ρ‡ΠΈΡ‚Π°ΡŽΡ‰ΠΈΠΉ ΠΈΡ…, ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ½ΠΈ появятся. Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΎΡ‡Π΅Π½ΡŒ Ρ€Π°ΡΡ‚ΠΎΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π² ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ЦП.

БистСмный Π²Ρ‹Π·ΠΎΠ² select позволяСт ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΆΠ΄Π°Ρ‚ΡŒ прибытия Π΄Π°Π½Π½Ρ‹Ρ… (ΠΈΠ»ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π²Ρ‹Π²ΠΎΠ΄Π°) ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π½Π° Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… дСскрипторах. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° эмулятора Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Ρƒ Π½Π΅Π΅ Π½Π΅ появится Ρ€Π°Π±ΠΎΡ‚Π°. Аналогичным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ сСрвСр ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Π΄Π΅Π»ΠΎ с многочислСнными ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ, оТидая запросы ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π½Π° ΠΌΠ½ΠΎΠ³ΠΈΡ… ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… сокСтах.

Ѐункция select ΠΎΠΏΠ΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ структурами Π΄Π°Π½Π½Ρ‹Ρ… fd_set, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΌΠΈ собой мноТСства ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… дСскрипторов. Для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ этих мноТСств ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Π½Π°Π±ΠΎΡ€ макросов:

#include <sys/types.h> #include <sys/time.h>

void FD_ZERO(fd_set *fdset);

void FD_CLR(int fd, fd_set *fdset);

void FD_SET(int fd, fd_set *fdset);

int FD_ISSET(int fd, fd_set *fdset);

Как ΠΈ прСдполагаСтся Π² соотвСтствии с ΠΈΡ… ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ, макрос FD_ZERO ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ структуру fd_set пустым мноТСством, FD_SET ΠΈ FD_CLR Π·Π°Π΄Π°ΡŽΡ‚ ΠΈ ΠΎΡ‡ΠΈΡ‰Π°ΡŽΡ‚ элСмСнты мноТСства, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΌΡƒ дСскриптору, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠΌΡƒ ΠΊΠ°ΠΊ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ fd, Π° макрос FD_ISSET Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ссли Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ссылаСтся fd, являСтся элСмСнтом структуры fd_set, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ fdset. МаксимальноС количСство Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… дСскрипторов Π² структурС Ρ‚ΠΈΠΏΠ° fd_set задаСтся константой FD_SETDIZE.

Ѐункция select ΠΌΠΎΠΆΠ΅Ρ‚ Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ оТидания, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΌΠ΅ΡˆΠ°Ρ‚ΡŒ бСсконСчной Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ΅. Π­Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ задаСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ структуры struct timeval. Она ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° Π² Ρ„Π°ΠΉΠ»Π΅ sys/time.h ΠΈ содСрТит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ элСмСнты:

struct timeval {

 time_t tv_sec; /* Π‘Π΅ΠΊΡƒΠ½Π΄Ρ‹ */

 long tv_usec;  /* ΠœΠΈΠΊΡ€ΠΎΡΠ΅ΠΊΡƒΠ½Π΄Ρ‹ */

}

Π’ΠΈΠΏ time_t, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ Π² Ρ„Π°ΠΉΠ»Π΅ sys/types.h, β€” цСлочислСнный. БистСмный Π²Ρ‹Π·ΠΎΠ² select ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

#include <sys/types.h>

#include <sys/time.h>

int select(int nfds, fd_set *readfds, fd_set *writefds,

 fd_set *errorfds, struct timeval *timeout);

Π’Ρ‹Π·ΠΎΠ² select позволяСт ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Π½Π΅ Π³ΠΎΡ‚ΠΎΠ² Π»ΠΈ хотя Π±Ρ‹ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· мноТСства Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… дСскрипторов ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ ΠΈΠ»ΠΈ записи, ΠΈΠ»ΠΈ находится Π»ΠΈ Π² ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ ΠΈΠ·-Π·Π° состояния ошибки ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ Π΄ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° готовности ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· дСскрипторов.

АргумСнт nfds Π·Π°Π΄Π°Π΅Ρ‚ количСство провСряСмых Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… дСскрипторов, ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ Π² Π²ΠΈΠ΄Ρƒ дСскрипторы ΠΎΡ‚ 0 Π΄ΠΎ nfds-1. КаТдоС ΠΈΠ· Ρ‚Ρ€Π΅Ρ… мноТСств дСскрипторов ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ пустым ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ, Ρ‚ΠΎΠ³Π΄Π° связанный с Π½ΠΈΠΌ тСст Π½Π΅ выполняСтся.

Ѐункция select Π²Π΅Ρ€Π½Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅, Ссли ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΈΠ· дСскрипторов Π² мноТСствС readfds Π³ΠΎΡ‚ΠΎΠ² ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ, ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ дСскриптор ΠΈΠ· мноТСства writefds Π³ΠΎΡ‚ΠΎΠ² ΠΊ записи ΠΈΠ»ΠΈ Ρƒ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· дСскрипторов мноТСства errorfd Π΅ΡΡ‚ΡŒ состояниС ошибки. Если Π½ΠΈ ΠΎΠ΄Π½ΠΎ ΠΈΠ· условий Π½Π΅ ΡΠΎΠ±Π»ΡŽΠ΄Π°Π΅Ρ‚ΡΡ, select Π²Π΅Ρ€Π½Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ послС ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΊΠ° Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ timeout. Если ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ timeout β€” пустой ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΠΈ Π½Π΅Ρ‚ активности Π½Π° сокСтах, Π²Ρ‹Π·ΠΎΠ² ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ Π½Π° Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ врСмя.

Когда select Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅, мноТСства дСскрипторов Π±ΡƒΠ΄ΡƒΡ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π½Π° Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ ΠΊ Ρ‡Ρ‚Π΅Π½ΠΈΡŽ ΠΈΠ»ΠΈ записи ΠΈΠ»ΠΈ ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠ΅ ошибки дСскрипторы. Для ΠΈΡ… ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ макрос FD_ISSET, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ дСскрипторы Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ внимания. МоТно ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ timeout для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ врСмя, ΠΎΡΡ‚Π°ΡŽΡ‰Π΅Π΅ΡΡ Π΄ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΈΡ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ оТидания, Π½ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π½Π΅ Π·Π°Π΄Π°Π½ΠΎ стандартом X/Open. ΠŸΡ€ΠΈ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΈΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ оТидания всС мноТСства дСскрипторов Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‡ΠΈΡ‰Π΅Π½Ρ‹.