并发服务器

当服务一个客户请求可能花费较长时间时,我们并不希望整个服务器被单个客户长期占用,而是希望同时服务多个客户

unix中编写并发服务器程序最简单的方法就是fork一个子进程来服务每个客户

======================

典型的并发服务器程序轮廓

=====================

pid_t pid;
int listenfd,connfd;
listenfd = socket(...);
bind(listenfd,...);
for(;;)
{
    connfd = accept(listenfd,...);
    if((pid = fork()) == 0)
    {
        close(listenfd);//子进程关闭listening socket
        doit(connfd);//处理请求
        close(connfd);//客户执行完毕,关闭已经连接的socket
        exit(0);//子进程结束
    }
    close(connfd);//父进程关闭已经连接的socket
}

当一个连接i建立时,accpt返回,服务器接着调用fork,然后由子进程服务客户,父进程则等待另一个连接

既然新的客户由子进程提供服务,父进程就关闭已连接套接字

 

对一个TCP套接字调用close会导致发送一个FIN,随后是正常的TCP连接终止序列

但为什么父进程调用close没有终止它与客户的连接呢?

我们必须知道每个文件或套接字都有一个引用计数,引用计数在文件表项中记录,他是当前打开着的引用该文件或套接字的个数

 

socket返回后与listenfd关联的文件表项的引用记数值为1

accept返回后与connfd关联的文件表项的引用计数为1

然而fork返回后,这2个描述符就在父进程与子进程间共享(被复制一份到子进程),因此与这2个套接字相关连的文件表项各自的访问计数值均为2

这么一来,当父进程关闭connfd时,它只是把相应的引用计数值从2减为1

该套接字真正的清理和资源释放需要等到其引用计数值达到0时才发生

posted @ 2016-04-03 19:54  ailx10  阅读(212)  评论(0编辑  收藏  举报