C SELECT: синтаксис и примеры использования

С select в языке программирования C можно реализовать многопоточность и выполнение одновременно нескольких задач без блокировки других потоков исполнения.

Функция select позволяет проверять состояние одного или нескольких файловых дескрипторов на предмет готовности к чтению, записи или ошибке. Она блокирует выполнение программы до тех пор, пока не произойдет событие, ожидаемое в функции select или не выйдет таймаут.

Пример использования select для чтения из нескольких сокетов:


#include 
#include 
#include 
#include 
#define MAX_LINE 1024
int main(int argc, char **argv) {
  int sockfd[3];
  struct sockaddr_in servaddr[3];
  socklen_t len = sizeof(servaddr[0]);
  char buf[MAX_LINE];
  int maxfd, nready, n;
  // создание трех сокетов и подключение к серверам
  sockfd[0] = socket(AF_INET, SOCK_STREAM, 0);
  sockfd[1] = socket(AF_INET, SOCK_STREAM, 0);
  sockfd[2] = socket(AF_INET, SOCK_STREAM, 0);
  // установка параметров серверов 
  bzero(&servaddr[0], len);
  servaddr[0].sin_family = AF_INET;
  servaddr[0].sin_port = htons(10000);
  inet_pton(AF_INET, "127.0.0.1", &servaddr[0].sin_addr);
  bzero(&servaddr[1], len);
  servaddr[1].sin_family = AF_INET;
  servaddr[1].sin_port = htons(20000);
  inet_pton(AF_INET, "127.0.0.1", &servaddr[1].sin_addr);
  bzero(&servaddr[2], len);
  servaddr[2].sin_family = AF_INET;
  servaddr[2].sin_port = htons(30000);
  inet_pton(AF_INET, "127.0.0.1", &servaddr[2].sin_addr);
  // подключение к серверам
  connect(sockfd[0], (struct sockaddr *) &servaddr[0], len);
  connect(sockfd[1], (struct sockaddr *) &servaddr[1], len);
  connect(sockfd[2], (struct sockaddr *) &servaddr[2], len);
  // определение максимального дескриптора для вызова select
  maxfd = sockfd[2];
  // цикл приема сообщений от серверов
  while(1) {
    fd_set rset;
    FD_ZERO(&rset);
    // добавление сокетов в множество наблюдения
    FD_SET(sockfd[0], &rset);
    FD_SET(sockfd[1], &rset);
    FD_SET(sockfd[2], &rset);
    // вызов select и ожидание наступления готовности к чтению
    nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
    if (FD_ISSET(sockfd[0], &rset)) {
      if ((n = read(sockfd[0], buf, MAX_LINE)) == 0) {
        printf("server[0] закрыл соединение\n");
        close(sockfd[0]);
        FD_CLR(sockfd[0], &rset);
      } else {
        buf[n] = '\0';
        printf("server[0]: %s\n", buf);
      }
    }
    if (FD_ISSET(sockfd[1], &rset)) {
      if ((n = read(sockfd[1], buf, MAX_LINE)) == 0) {
        printf("server[1] закрыл соединение\n");
        close(sockfd[1]);
        FD_CLR(sockfd[1], &rset);
      } else {
        buf[n] = '\0';
        printf("server[1]: %s\n", buf);
      }
    }
    if (FD_ISSET(sockfd[2], &rset)) {
      if ((n = read(sockfd[2], buf, MAX_LINE)) == 0) {
        printf("server[2] закрыл соединение\n");
        close(sockfd[2]);
        FD_CLR(sockfd[2], &rset);
      } else {
        buf[n] = '\0';
        printf("server[2]: %s\n", buf);
      }
    }
  }
  return 0;
}

В этом примере программа создает три сокета и подключается к серверам с адресами 127.0.0.1 и портами 10000, 20000 и 30000. Затем в цикле она вызывает функцию select и ожидает наступления готовности сокетов к чтению. Если сокет готов к чтению, программа читает из него данные и выводит на экран. Если сервер закрыл сокет, программа закрывает соединение и удаляет дескриптор из множества наблюдения.

Похожие вопросы на: "c select "

Исключения (Exceptions) в программировании: базовые понятия и примеры работы
Round Robin: правила, преимущества и недостатки
Blazor: новый шаг в развитии веб-разработки
Hoogle: поисковик для поиска всего в Интернете
Как узнать длину массива в PHP: примеры и объяснение функции count()
Double Java - удвой свой опыт в программировании на Java
Функция fprintf: вывод данных в языке программирования
FindIndex - быстрый и точный поиск информации онлайн
Линтинг или как исключить ошибки из вашего кода
Градиенты CSS: создание красивых переходов цвета