.net 多线程:在什么情况下创建的线程过多?

.net 多线程:在什么情况下创建的线程过多?,.net,multithreading,.net,Multithreading,我正在开发一个多线程应用程序 这个应用程序一开始是一个单线程,后来扩展到多个线程,以实现性能的提高 我有一个主线程,它将工作划分为更小的块,并将其卸载到处理这些块的工作线程。这一部分是使用信号量控制的,一次只允许X个工作线程。工作线程生成数据块,这些数据块存储在队列或环形缓冲区中,然后由一个保存线程读取。此线程负责将数据块保存到磁盘(有时通过本地网络) 我的开发机器是一个8GB内存的四核。使用3个工作线程和1个保存线程在我的机器上运行应用程序,可以在网络上实现稳定的数据流,处理器的平均利用率为7

我正在开发一个多线程应用程序

这个应用程序一开始是一个单线程,后来扩展到多个线程,以实现性能的提高

我有一个主线程,它将工作划分为更小的块,并将其卸载到处理这些块的工作线程。这一部分是使用信号量控制的,一次只允许X个工作线程。工作线程生成数据块,这些数据块存储在队列或环形缓冲区中,然后由一个保存线程读取。此线程负责将数据块保存到磁盘(有时通过本地网络)

我的开发机器是一个8GB内存的四核。使用3个工作线程和1个保存线程在我的机器上运行应用程序,可以在网络上实现稳定的数据流,处理器的平均利用率为75%

解决此问题的第二种方法是在工作线程和保存线程之间添加另一组线程(即从当前工作线程中取出一个任务并将其添加到另一个线程)(我还为每个线程添加一个队列)在我的机器上,应用程序似乎没有获得任何速度,因为似乎存在太多资源争用、RAM总线饱和和处理器争用

通过对线程数量及其优先级的大量实验,我找到了我的机器的理想设置,包括处理此问题的第一种和第二种方法。现在生产机器将有8个内核和64GB的RAM。一个完全不同的环境和应用程序将必须为此进行配置

我的问题是,在什么时候创建了太多线程?确定给定机器的理想设置总是一个实验问题吗?是否有一种方法可以确定或观察锁是否从应用程序中拿走了太多东西


(我不使用线程池,因为它不适合由信号量和其他锁定机制管理的长时间运行的线程。)

当您的应用程序的整体性能下降或对同一机箱上运行的其他应用程序的影响达到不可接受的程度时,您创建了太多线程

关键是没有绝对的答案

我一直在开发的一个应用程序使用了1000个线程的线程池,对于我们正在做的事情来说,这个数字似乎是正确的。在一个配置中,我们没有限制它,它上升到30000+并且基本上使机器停止运转

基本上,您必须对其进行性能测试,并有足够的监视/检测来确定应用程序的总体吞吐量、资源使用率、线程利用率,并了解线程的空闲程度以及等待接收队列的工作时间。然后根据需要调整


注意:在添加另一层线程之前,请仔细考虑。我相信您知道,编写多线程代码很难。尽量使它尽可能简单。添加另一层是一个危险的步骤。

没有人能给你一个简单的数字答案,因为它太依赖于机器有多少内核&c,而且还依赖于所述机器与你的应用程序同时执行的其他任务(如果有的话),以及你的线程也在做什么

举一个后一个问题的例子:我曾经有一个非常简单的“爬虫程序”,其中有一定数量的线程用于我确定需要的HTTP GET页面——每个线程的大部分时间都被阻塞在套接字调用中以执行HTTP GET,因此要获得相当好的性能,我需要大量的线程(数百个)。后来,我改变了底层的方法,使用异步网络I/O而不是阻塞套接字——突然间,每个线程都很容易有数百个URL“在运行”,因此,如果有数百个这样的线程处于活动状态,可能会使系统不知所措,可能会导致系统无法处理更多的套接字(它不是一个非常大或配置不充分的服务器!-)导致崩溃,或者至少由于过度交换等原因导致严重的速度减慢

因此,即使对于完全受I/O限制的线程,它们所使用的I/O的确切形式(例如,阻塞或异步)也会对某个总体软件任务的最佳线程数(或进程或任何其他此类单元)产生巨大影响。显然,执行更多CPU限制工作的线程必须进行校准(以获得最大性能)取决于内核的可用性,以及内核可以在其中工作的RAM的可用性,但也可能取决于其他资源的可用性(例如,如果您的一些线程能够使用可用的GPU或其他专用处理单元来委派其部分工作)


最后,一旦你知道了所有这些参数,你就可以做出一个合理的大概估计,但是你可能会偏离一个重要因素——因此,在一个现实的工作负载上进行基准测试在部署的后期性能优化阶段,线程数量是您估计的最佳线程数量的一半,也是最佳线程数量的两倍,这是花费一些时间和资源的一种很好的方式。一般来说,性能行为往往会让非常有经验的架构师、开发人员和系统管理员感到惊讶,因此没有真正的解决方法od替代了现实基准的经验数据驱动方法,仔细测量并相应调整。(请注意,盲目的经验主义——只是试图适应实验观察,而没有任何合理的模型来理解它们——几乎和忽视数据的教条主义和教条主义方法一样糟糕,但是,这是另一种咆哮;-)。

+1爬山方法似乎是解决这个问题最可靠的方法之一