В сетевом программировании Unix есть пример предварительно разветвленного сервера, который использует передачу сообщений по доменному каналу Unix для указания дочерним процессам обработки входящего соединения:
for ( ; ; ) {
rset = masterset;
if (navail <= 0)
FD_CLR(listenfd, &rset); /* turn off if no available children */
nsel = Select(maxfd + 1, &rset, NULL, NULL, NULL);
/* 4check for new connections */
if (FD_ISSET(listenfd, &rset)) {
clilen = addrlen;
connfd = Accept(listenfd, cliaddr, &clilen);
for (i = 0; i < nchildren; i++)
if (cptr[i].child_status == 0)
break; /* available */
if (i == nchildren)
err_quit("no available children");
cptr[i].child_status = 1; /* mark child as busy */
cptr[i].child_count++;
navail--;
n = Write_fd(cptr[i].child_pipefd, "", 1, connfd);
Close(connfd);
if (--nsel == 0)
continue; /* all done with select() results */
}
Как видите, родительский файл записывает номер дескриптора файла для сокета в канал, а затем вызывает close для дескриптора файла. Когда преформированные потомки заканчивают работу с сокетом, они также вызывают close в дескрипторе. То, что бросает меня в тупик, заключается в том, что, поскольку эти дочерние элементы предварительно разветвляются, я предполагаю, что только те файловые дескрипторы, которые существовали в то время, когда дочерние элементы были разветвлены, будут доступны совместно. Однако, если бы это было правдой, то этот пример эффектно провалился бы, но все же он работает.
Может ли кто-нибудь пролить свет на то, как дескрипторы файлов, созданные родительским после того, как разветвление в конечном итоге стало доступно процессу потомков?