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

Рассмотрим сначала функцию 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 [ ] <#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++) {

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

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

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

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

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

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

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