Program executing slow when running many threads
我已经用C#编写了一个程序,使用不同的线程可以完成许多并行工作。 当我达到大约300个线程时,程序的GUI开始变得缓慢,线程的执行速度也急剧下降。 线程正在从另一台计算机上运行的mySQL数据库读取和写入数据。
有趣的是,如果我将工作分配到同一台机器上的两个进程之间,则一切运行得都很好。 .net框架或Windows中每个进程都有线程限制吗? 还是为什么我会得到这种行为? 可能是与网络相关的问题吗? 我正在运行Windows 7 Ultimate,并且我尝试了VS2010和VS 2012具有相同的行为。
-
300个线程似乎有点多余。 您如何创建这些线程? 他们是线程池线程吗?
-
您是否为进程明确地应用了(或已应用了系统管理员)任何CPU配额?
-
什么是CPU配额? 它在通用Win 7上运行。AMD X6 4GB内存。
-
@ user1703285-那就是我的想法-只是消除了系统性能异常的一种可能性。 我不得不说我现在没什么了:(
-
我可能会忽略任何网络连接限制吗? 我尝试在app.config中设置maxconn ection,但没有任何性能提高。
-
数据库服务器在什么操作系统上运行?
-
300个线程<--->从mySQL数据库读取和写入数据。 ut
-
我没有使用线程池。 胎面都是长时间运行的螺纹,最多可以工作10个小时。
-
关于我应该寻找的内容的任何想法都可以判断这是与线程或网络相关的问题。
300个线程很傻。
线程数应在系统支持的核心数(2..8)和/或最大同时连接数(有时通过TCP最多4个)的范围内。
超越此限制,您只会浪费内存,每个线程1 MB。在32位系统中,300 MB已经占用了大量可用的内存空间。我假设每个线程都附加了一些缓冲区。
如果2个单独的进程的性能优于1,则可能不是上下文切换,而是内存使用或连接限制使您退缩。
-
连接限制-也许。 OP症状似乎仍然有些奇怪。一个进程/ 300个线程确实很糟糕,两个进程/ 150个线程完美。奇怪。
分配处理器时间的方式是:操作系统为每个进程分配处理器时间,然后每个进程为每个线程分配时间。
因此,两个进程将获得两倍的处理器时间,这就是为什么如果将程序分为两个进程,它将更快地工作。
如果要使GUI运行更流畅,只需为该线程设置更高的优先级即可。
这样,GUI线程将比其他线程获得更多的处理器时间,但不会那么多,以至于它将显着降低其他线程的速度。
-
好的,那么一个过程不应该能够利用所有系统的性能吗?
-
嗯..在特定时间有数十个流程正在打开。如果有19个进程并且您打开了一个进程,那么您将以操作系统提供的20个单位中的1个单位来处理处理器时间,因为还有19个其他进程需要时间。但是,如果您有两个进程处于打开状态,那么您将获得操作系统提供的21个单位中的2个单位的处理器时间,因此处理器时间几乎增加了一倍。
-
@ user1703285这取决于进程优先级。如果您具有最高的优先级(实时),并且每个内核都具有完整的CPU消耗(例如while (true) {}),则可以。但是,当有许多进程正在运行,并且您的优先级低于高优先级时,其他进程也会消耗CPU。
-
OP还应该查找"上下文切换"的概念及其副作用。更多线程并不总是意味着更好的性能。
-
它作为两个过程而不是一个过程运行得更好的事实并不能由此解释。每当收到新消息时,GUI线程都会获得优先级提升。因此,人为地增加优先级可能不会有所作为。
-
分配处理器时间的方式是操作系统为每个线程分配处理器时间。一些线程可能属于同一进程。执行单位是线程,而不是进程。除非应用了一些基于进程的CPU配额(在Windows上不是默认设置),否则没人能回答OP问题。
-
@Brady-OP具有两种情况,均具有300个线程。一个是坏的,另一个是完美的。
-
@IonutHulub-我敢打赌那也不会改变太多。我看的越多,就越怀疑mySQL的某些限制/配置/问题。可能是Hank建议的某些每个进程的连接限制。我希望我知道答案,或者甚至更好地猜测,这将是解释症状的更好方法,但是没有:((
-
尝试将线程优先级设置为高-不变。可能是.net网络连接限制吗?
使用线程池。这将通过限制现有线程数自动根据您的系统分配最佳线程数。您也可以随时设置允许的最大线程数。
另外,如果要从for循环,foreach循环或linq语句中分配线程以并行化任务,则应查看Parallel Class或PLINQ。
-
对长时间运行的线程使用线程池不是一个好主意。默认情况下,线程池的活动线程数等于内核/处理器数。由于线程处于活动状态,因此无法维持该最小值,因此该池每秒启动一个新线程以容纳等待的请求。也就是说,可能需要一段时间才能运行300。框架和系统的其他部分使用线程池,将其用于长时间运行的线程会影响使用该池的所有其他内容
首先,如果您有300个应用程序线程,那么您可能应该重新考虑程序设计。
设置GUI线程优先级可以使GUI的性能更好。但是,如果您运行大量线程,则OS必须在程序堆栈中分配空间。并且堆栈是内存的连续部分。因此,每次创建新线程时,为堆栈分配的内存空间可能无法容纳新线程。然后,操作系统必须必须在内存中分配更大的连续空间,并将所有数据从旧堆栈复制到新堆栈。因此,显然这可能会导致程序性能下降。
-
每当收到新消息时,GUI线程都会获得优先级提升。因此,人为地增加优先级可能不会有所作为。 GUI线程做的不多;它呆滞的事实表明存在另一个问题。提高GUI线程的优先级可能不会产生明显的效果。
-
@彼得,我同意你的看法。应用程序的设计应更改。
-
?每个线程都有自己的堆栈,并且堆栈是可交换的。很少运行的线程不会占用大量资源。 300个线程对于某些应用程序来说并非没有道理。一些联网的应用程序。在我的系统上,System有259个线程,Kaspersky 95和Sidebar 67。
-
正在运行300个线程,每个线程在远程计算机上运行MYSQL查询。因此它们应该具有数据库连接。我认为这与您的情况不同。
对于这个问题的公认答案可能会解释发生了什么,但是对于任何普通应用程序来说,300个线程对于许多人来说似乎是一个好主意。
-
是的,我知道它的线程太多。但是为什么将其分为两个过程却能起作用?
-
@ user1703285,可能是因为2个进程的"上下文切换"比300个线程少得多。
-
h?为什么要这样做有什么不同?一个进程/ 300个线程,两个进程/ 150个线程。它的线程数相同!
-
@MartinJames好吧,我不明白这是2个进程,每个进程有150个线程。我知道这是1个具有300个线程的进程,而2个进程可能是没有线程的分支。
-
它是一个具有300个线程的进程,而两个进程分别具有150个线程。
-
@ user1703285-是的,这就是为什么它如此奇怪的原因。我从没尝试过/见过它,所以我真的很好奇它为什么会发生(如果它也咬住了我:)。