IT干货网

c#之线程池极端性能滞后

pengyingh 2024年12月31日 编程设计 25 0

关于这个问题已经有很多讨论,但它们似乎无法解释我的特定问题。 在使用 ThreadPool 而不是 Thread 类进行线程处理时,我遇到了严重的性能问题。

细节:

我已经构建了一个 tcp 服务器,当 tcp 服务器接受一个新客户端时,它会生成一个新线程来处理该客户端。一切都相当简单,但我的服务器需要很长时间才能处理许多并发客户端。大约 35 个仅发送 2048 字节缓冲区、接收并关闭的简单客户端需要 30 秒。

经过多次停站后,我发现 ThreadPool.QueueUserWorkItem最多需要 26 秒。我用它来产生处理新客户的新线程。
更换后ThreadPool.QueueUserWorkItemnew Thread()我的表现提高到不到一秒。

我想解释一下为什么会发生这种情况。

澄清:

Delay 与客户端代码无关,从调用 ThreadPool.QueueUserWorkItem 到启动 clientMsgHandler.HandleIncomingMsgs 20 秒可以过去。

延迟从第一个线程开始,随着测试的继续,实际上会略有改善。我对解决方案不太感兴趣,而对解释为什么会发生更感兴趣。
客户端确实阻塞了,但只是很短的一段时间。

服务器代码:

private void AddTcpClientMsgHandler(TcpClient tcpClient) 
    { 
        //lock so no addition of client and closure can occur concurrently 
        Stopwatch watch = new Stopwatch(); 
        watch.Start(); 
        Monitor.Enter(this); 
        int pWatchIdx =  watchIDX++; 
        if (!isOpen) 
            throw new ObjectDisposedException(ResourceAlreadyClosed); 
 
        TcpClientMsgHandler clientMsgHandler = CreateClientHandler(tcpClient);                                          
        clientMsgHandlerManager.AddTcpClientMsgHandler(clientMsgHandler); 
        //ThreadPool.QueueUserWorkItem(clientMsgHandler.HandleIncomingMsgs); takes 20 seconds to run 
        Thread thread = new Thread(clientMsgHandler.HandleIncomingMsgs); 
        thread.Start(); 
        watch.Stop(); 
        Monitor.Exit(this); 
        Console.WriteLine(string.Format("Iteration {0} took {1} Client {2}", pWatchIdx.ToString(),watch.Elapsed, tcpClient.Client.RemoteEndPoint)); 
 
    } 

请您参考如下方法:

阻塞代码是线程池的敌人。从您发布的示例中,无法判断阻塞发生的位置,但我建议您查看代码路径以找出代码阻塞的位置。在调试器中运行您的服务器,直到它开始显示高延迟,然后中断执行并查看 VS 的线程面板。这将显示线程阻塞的位置。这很可能是在同步 IO 上。考虑用异步代码替换。


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!