You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TCP服务器先sleep再关闭socket导致无法处理并发请求问题

TCP服务器交换sleep与socket关闭顺序后并发失效的原因分析

原程序正常并发的逻辑

你的服务器启动了5个子进程,所有子进程共享同一个监听套接字sfd。原代码中,子进程处理连接的流程是:

  1. 调用accept获取新连接的connfd
  2. 向客户端发送时间戳
  3. 立即调用fclose(fp)关闭连接(fclose会间接关闭connfd)
  4. 睡眠5秒

这种情况下,每个子进程处理完一个连接后会快速释放自己的"处理能力"——关闭连接后,子进程会回到循环开头重新调用accept,等待新的连接请求。当有多个客户端同时连接时,5个子进程可以各自处理一个连接,空闲的子进程会继续响应新请求,所以并发是正常的。

交换顺序后并发失效的核心原因

当你把sleep(5)和fclose(fp)的顺序调换后,子进程的处理流程变成:

  1. 获取连接并发送时间戳
  2. 先睡眠5秒
  3. 睡眠结束后才关闭连接

问题出在睡眠的5秒内,当前子进程被阻塞在sleep调用上,无法回到循环开头执行accept。因为你只有5个子进程,当同时有5个客户端连接时,所有子进程都会进入睡眠状态,没有任何子进程能处理新的连接请求。后续的客户端请求会被积压在监听队列中,直到某个子进程睡眠结束、关闭连接并回到accept调用时,才能被处理——这就导致服务器看起来完全失去了并发能力。

另外需要注意:

  • 监听套接字sfd是被所有子进程共享的,内核会在有新连接时唤醒等待在accept上的子进程,这部分逻辑没有问题。
  • fclose(fp)不仅会关闭文件流,还会关闭底层的connfd,释放该连接的资源;而睡眠期间connfd处于打开状态,但子进程无法处理新请求,属于资源占用但闲置的状态。

关键代码对比

原正常逻辑:

fprintf(fp, MSG_TYPE, time(NULL));

fclose(fp); // 立即关闭连接,释放处理能力
sleep(5);   // 睡眠期间子进程已回到accept等待

交换后失效逻辑:

fprintf(fp, MSG_TYPE, time(NULL));

sleep(5);   // 子进程被阻塞,无法处理新连接
fclose(fp); // 睡眠结束后才释放连接

内容的提问来源于stack exchange,提问作者477

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:53:28