C语言HTTP服务器关闭fd后仍出现文件描述符持续增长不复用问题咨询
问题解答
1. 文件描述符持续上涨及accept: too many open files报错原因
- Linux内核给进程分配文件描述符(fd)的规则是永远取当前可用的最小非负整数,你观察到fd偶尔能回到4,说明确实有部分fd被正常关闭,但整体数值持续上涨,本质是存在隐性的文件描述符泄漏,你以为所有fd都关了,实际上有部分类型的fd被遗漏:
- 除了
accept()返回的连接fd、磁盘文件fd外,pipe()、eventfd()、timerfd()、socket()(客户端请求用的socket)、epoll_create()返回的实例fd等都会占用fd编号,常见的泄漏场景包括:非阻塞connect失败的fd未关闭、域名解析相关句柄未释放、调用第三方库时内部创建的fd未释放等。 - TIME_WAIT状态的TCP连接不会占用进程的fd配额,因此该问题和TCP状态无关。
- 除了
accept: too many open files报错的含义是:当前进程持有的打开文件描述符总数已经触及该进程的打开文件数(nofile)上限,内核无法为新的连接分配fd,因此accept()调用失败。- 你当前贴的
/proc/$$/fd输出是你当前操作shell的fd列表,不是HTTP服务进程的,你可以执行ls -la /proc/80902/fd(你的服务进程PID是80902)查看所有打开的fd对应的资源,直接定位泄漏点。
注:你补充的两个命令输出写反了,第一份是
ls -la /proc/$$/fd的执行结果,第二份才是ps aux | grep lh的执行结果。
2. ulimit -n配置的生效规则
ulimit是shell会话级别的临时配置,不是系统全局永久配置:
- 你在当前shell窗口执行
ulimit -n 10000,仅对当前shell窗口启动的子进程生效,关闭该shell窗口后配置就失效,新打开的shell窗口会读取系统默认的nofile值。 - 如果需要永久生效不需要重启系统,只需要修改
/etc/security/limits.conf,添加如下两行配置:
保存后重新登录用户即可生效。* soft nofile 10000 * hard nofile 10000
3. pts/4的含义
pts是伪终端(Pseudo Terminal Slave)的缩写,pts/4是系统中第4个伪终端设备,不是文件描述符编号:
ps aux输出中该列表示进程绑定的控制终端,你是在编号为4的伪终端窗口中执行的sudo ./lh命令,因此服务进程的控制终端显示为pts/4,如果关闭这个终端窗口,绑定在该终端的前台进程会收到SIGHUP信号退出。- 你贴的fd列表中
0 -> /dev/pts/3的含义是:当前shell的0号标准输入fd,绑定到了编号为3的伪终端设备。
内容的提问来源于stack exchange,提问作者user786
相关产品推荐
相关产品推荐

