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

概述

一种典型的并发服务器程序轮廓,利用的是多进程实现。当然还可以基于I/O多路复用,多进程方法实现并发服务器。

代码实现简要的轮廓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pid_t pid;
int listenfd, connfd;

listenfd = Socket(...);

/* fill in sockaddr_in{} with server's well-known port */
Bind(listenfd, ...);
Listen(listenfd, LISTENQ);

for(; ; ){
connfd = Accept(listenfd, ...); /* probably blocks */

if( (pid = Fork()) == 0 ){
Close(listenfd); /* child closes listening socket */
do_it(connfd); /* process the request */
Close(connfd); /* done with this client */
exit(0); /* child terminates */
}

Close(connfd); /* parent closes connected socket */
}

思考

父进程关闭了已连接描述符后,子进程为什么仍然能够使用该描述符和客户端通信?

解释

当父进程派生子进程时,它得到一个已连接描述符的副本,并将相关文件表中的引用计数从1增加到2。当父进程关闭它的描述符副本时,
引用计数就从2减少到1。因为内核不会关闭一个文件,直到文件表中它的引用计数值变为零,所以子进程这边的连接端将保持打开。