我正在通过两种方法维护其他正在使用多线程的代码:
1: ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf ReadData), objUpdateItem)
2: Dim aThread As New Thread(AddressOf LoadCache)
aThread.Start()
然而,在双核机器上,我只获得50%的CPU使用率,并且在具有超线程启用机器的双核上,我只获得25%的CPU利用率。
显然线程非常复杂,但这种行为似乎表明我不理解一些简单的基本事实?
代码太复杂了,不幸发布在这里,但为了参考目的,这里大致发生了什么....我有大约500个帐户,其数据从数据库加载到内存缓存...每个帐户单独加载,该进程首先调用一个长时间运行的存储过程,然后操作和缓存返回的数据。因此,在这种情况下线程化的关键是确实存在一个瓶颈命中数据库(即:线程将被闲置最多30秒等待查询返回),因此我们通过线程允许其他人开始处理他们从Oracle收到的数据。
因此,主线程执行:
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf ReadData), objUpdateItem)
然后,ReadData()然后继续执行(恰好一次):
Dim aThread As New Thread(AddressOf LoadCache)
aThread.Start()
这是在递归函数中发生的,因此QueueUserWorkItem可以多次执行,然后通过aThread.Start执行一个新线程
希望这可以很好地了解事情的发生方式。
那么,在这种情况下,理论上这不应该两个核心,而不是在一个核心上达到100%,而另一个核心本质上是空闲的吗?
答案 0 :(得分:4)
该代码启动一个将执行某项操作的线程。要获得多个核心工作,您需要启动多个线程并使它们都忙碌。启动一个线程做一些工作,然后让你的主线程等待它将不会更快地完成任务。通常在后台线程上启动一个长时间运行的任务,以便UI保持响应,这可能是此代码的目的,但它不会使任务更快地完成。
@Judah Himango - 我假设这两行代码是如何在程序的两个不同位置实现多线程的样本。也许OP可以澄清是否是这种情况,或者这两条线是否真的在一种方法中。如果它们是一种方法的一部分,那么我们需要看看这两种方法实际上在做什么。
更新:
这听起来似乎应该最大化两个核心。通过递归调用ReadData()是什么意思?如果每个新线程只在其末端或附近调用ReadData以启动下一个线程,那么这可以解释您所看到的行为。
我不确定这是一个好主意。如果存储的proc需要30秒才能获得数据,那么可能是它在数据库服务器上放置了一个公平的负载。并行运行500次只会让事情变得更糟。显然我不知道你的数据库或数据,但我会考虑提高存储过程的性能
如果多线程确实看起来像前进的方式,那么我将在主线程上有一个循环,为需要加载的每个帐户调用一次ThreadPool.QueueUserWorkItem。我也会删除显式线程创建,只使用线程池。这样,您就不太可能通过创建太多线程来使本地计算机饿死。
答案 1 :(得分:3)
你旋转了多少个线程?它可能看起来很原始(等待几年,你不再需要这样做了),但是你的代码必须弄清楚要启动的最佳线程数,然后调整那么多。简单地运行单个线程不会使事情变得更快,并且不会固定物理处理器,尽管它可能有其他原因(例如,工作者线程可以保持UI响应)。
在许多情况下,您需要运行多个线程,这些线程等于您可用的逻辑核心数(我相信可以从Environment.ProcessorCount获得),但它可能还有其他一些基础。例如,当我受到远程进程延迟的约束时,我已经开发了几十个线程,与不同的主机交谈。
答案 2 :(得分:2)
多线程和多核是两回事。做多线程经常不会为你提供巨大的性能提升,有时恰恰相反。操作系统可能会做一些技巧来将你的cpu周期分散到多个核心上,但这就是它结束的地方。
您正在寻找的是并行性。 .NET 4.0框架将添加许多新功能来支持Parallelism。在这里有一个潜行高峰:
http://www.danielmoth.com/Blog/2009/01/parallelising-loops-in-net-4.html
答案 3 :(得分:0)
CPU行为将指示应用程序仅使用一个逻辑处理器。 50%将是2个中的一个proc(proc + proc)。 25%将是4个中的一个逻辑处理器(proc + HT + proc + HT)
答案 4 :(得分:0)
总共有多少个线程,你是否在LoadCache中有任何锁定。 SyncLock可以将多线程系统充当单线程(按设计)。此外,如果您的唯一一个线程一个线程,您将只获得一个工作线程。
答案 5 :(得分:0)
CPU利用率表明您只使用一个核心;这可能表明你已经添加了线程到一个没有益处的部分(在这种情况下,CPU时间不是瓶颈)。
如果加载缓存或读取数据的速度非常快,多线程将无法大幅提升速度性能。同样,如果您遇到不同的瓶颈(服务器的带宽较慢等),它可能不会显示为CPU使用率。