UNIX: разработка сетевых приложений - Страница 353
Изменить размер шрифта:
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++) {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-37navailselectbackloglistenПрием нового соединения
39-55acceptwrite_fdМы всегда начинаем поиск свободного дочернего процесса с первого элемента массива структур
Childchild_countОбработка вновь освободившихся дочерних процессов
56-66child_mainread