多进程 accept
多进程网络编程中子进程在 fork 后应该先做什么处理再进行 fd 读写处理
pid_t pid;
int listenfd, connfd;
listenfd = Socket(...);
Bind(listenfd, ...);
Listen(listenfd, LISTENQ);
for(;;) {
connfd = Accept(listenfd, ...);
if( (pid = Fork()) == 0) {
Close(listenfd);
doit(connfd);
Close(connfd);
exit(0);
}
Close(connfd);
}
-
以上为经典并发服务器轮廓(节选至UNIX 网络变成卷1)
- 对于子线程来说不需要关注父进程的 listenfd,所以 fork 后应该先 close listenfd
- 新连接由子进程提供服务,所以父进程再 fork 后可以 close connfd
-
调用 close 是否会关闭 socket
- 实际上调用 close 只是导致相应的描述符引用计数减一,套接字真正的清理和资源释放发生需要其引用计数到达 0 时才发生
-
父进程为什么需要 close connfd
- 若不关闭,fork 结束后,connfd 的引用计数为2,子进程结束后,connfd 引用计数由 2递减为 1,(a)这将导致 fd 一直存在,耗尽父进程的可用文件描述符而且(b)连接会一直存在占用资源