Читаем UNIX: разработка сетевых приложений полностью

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 }

Отключение прослушиваемого сокета в случае отсутствия свободных дочерних процессов

36-37 Счетчик navail отслеживает количество свободных дочерних процессов. Если его значение становится равным нулю, прослушиваемый сокет в наборе дескрипторов функции select выключается. Это предотвращает прием нового соединения в тот момент, когда нет ни одного свободного дочернего процесса. Ядро по- прежнему устанавливает эти соединения в очередь, пока их количество не превысит значения аргумента backlog функции listen, заданного для прослушиваемого сокета, но мы не хотим их принимать, пока у нас не появится свободный дочерний процесс, готовый обрабатывать клиентский запрос.

Прием нового соединения

39-55 Если прослушиваемый сокет готов для считывания, можно принимать (accept) новое соединение. Мы находим первый свободный дочерний процесс и передаем ему присоединенный сокет с помощью функции write_fd, приведенной в листинге 15.11. Вместе с дескриптором мы передаем 1 байт, но получатель не интересуется содержимым этого байта. Родитель закрывает присоединенный сокет.

Перейти на страницу:

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

Изделия из древесины и материалов, имитирующих ее текстуру, привычным образом окружают нас в повседневной жизни, поэтому мы относимся к ней как к чему-то обыденному. Но как только ее коснется умелая рука мастера резьбы по дереву, рождается произведение искусства и раскрываются такие качества древесины, как богатая фактура, разнообразие цветов, особая теплота. Эта книга поможет читателю открыть для себя удивительный мир творчества и познать секреты резьбы по дереву. Автор надеется, что начинающие резчики найдут в ней интересный и полезный материал, который позволит им стать мастерами. В приложении представлены рисунки орнаментов и различных узоров, которые на первых порах можно копировать, а по мере приобретения навыка на их основе разрабатывать свои образцы.

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги