为何while循环中Task.Run因变量声明位置不同导致CPU占用差异巨大?
为什么将TcpClient变量移到while循环外会导致CPU占用接近100%?
正常CPU占用的代码
var localadd = IPAddress.Any; var server = new TcpListener(localadd, 6300); server.Start(); while (true) { var client = server.AcceptTcpClient(); Task.Run(() => ThreadProc(client)); } // The cpu cost is as normal as usual.
CPU占用接近100%的代码
var localadd = IPAddress.Any; var server = new TcpListener(localadd, 6300); server.Start(); var client = server.AcceptTcpClient(); while (true) { Task.Run(() => ThreadProc(client)); } // The cpu cost nearly 100%!!!
原因解析
第一个版本的核心是阻塞等待新连接:
server.AcceptTcpClient()是阻塞方法,没有客户端连接时,当前线程会进入休眠状态,完全不消耗CPU资源。只有当新客户端接入时,才会创建任务处理连接,之后再次回到阻塞等待状态,所以CPU占用保持正常。第二个版本的问题在于无限循环无阻塞:
server.AcceptTcpClient()仅执行一次,拿到第一个客户端连接后,就进入了while (true)的无限循环。这个循环内没有任何会让线程休眠或等待的逻辑,会以CPU的最高速度不断创建新任务去处理同一个client对象——循环完全没有停顿,直接把CPU的所有计算资源占满,导致占用率接近100%。
简单总结:前者是“等待连接→处理→等待”的有序循环,后者是“拿到一个连接后疯狂重复处理”的无停顿循环,后者的无阻塞特性直接耗尽了CPU资源。
内容的提问来源于stack exchange,提问作者KomiShao
相关产品推荐
相关产品推荐

