我正在阅读有关Thread pooling in VB的教程。 Fibonacci计算有一个例子:
Imports System.Threading
Module Module1
Public Class Fibonacci
Private _n As Integer
Private _fibOfN
Private _doneEvent As ManualResetEvent
Public ReadOnly Property N() As Integer
Get
Return _n
End Get
End Property
Public ReadOnly Property FibOfN() As Integer
Get
Return _fibOfN
End Get
End Property
Sub New(ByVal n As Integer, ByVal doneEvent As ManualResetEvent)
_n = n
_doneEvent = doneEvent
End Sub
' Wrapper method for use with the thread pool.
Public Sub ThreadPoolCallBack(ByVal threadContext As Object)
Dim threadIndex As Integer = CType(threadContext, Integer)
Console.WriteLine("thread {0} started...", threadIndex)
_fibOfN = Calculate(_n)
Console.WriteLine("thread {0} result calculated...", threadIndex)
_doneEvent.Set()
End Sub
Public Function Calculate(ByVal n As Integer) As Integer
If n <= 1 Then
Return n
End If
Return Calculate(n - 1) + Calculate(n - 2)
End Function
End Class
<MTAThread()>
Sub Main()
Const FibonacciCalculations As Integer = 9 ' 0 to 9
' One event is used for each Fibonacci object
Dim doneEvents(FibonacciCalculations) As ManualResetEvent
Dim fibArray(FibonacciCalculations) As Fibonacci
Dim r As New Random()
' Configure and start threads using ThreadPool.
Console.WriteLine("launching {0} tasks...", FibonacciCalculations)
For i As Integer = 0 To FibonacciCalculations
doneEvents(i) = New ManualResetEvent(False)
Dim f = New Fibonacci(r.Next(20, 40), doneEvents(i))
fibArray(i) = f
ThreadPool.QueueUserWorkItem(AddressOf f.ThreadPoolCallBack, i)
Next
' Wait for all threads in pool to calculate.
WaitHandle.WaitAll(doneEvents)
Console.WriteLine("All calculations are complete.")
' Display the results.
For i As Integer = 0 To FibonacciCalculations
Dim f As Fibonacci = fibArray(i)
Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN)
Next
End Sub
End Module
我启动了这个模块并且它正常工作,这只能处理9个计算:
Const FibonacciCalculations As Integer = 9
我增加了这些限制,但这可以处理多达63次计算。从第64次提出计算异常,说:
waithandle必须小于64
我希望这个应用程序能够处理N个计算。一个好主意可以为线程池设置上限(例如:6)。 N次计算将同时使用最多6个线程进行处理。我如何编辑代码来处理这个删除waitHandle
错误?
答案 0 :(得分:1)
对你可以在同一时间等待的手柄数量的winapi限制非常困难。没有必要,如果你等待每一个人,你会得到完全相同的结果:
' Wait for all threads in pool to calculate.
For i As Integer = 0 To FibonacciCalculations
doneEvents(i).WaitOne()
Next
并注意现在如何将它与下一个循环结合起来,使您的程序更有效率,因为您将计算与显示重叠。所以你真的想要支持这个:
' Display the results.
For i As Integer = 0 To FibonacciCalculations
doneEvents(i).WaitOne()
Dim f As Fibonacci = fibArray(i)
Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN)
Next
答案 1 :(得分:1)
如果要等待X> 63的X任务完成,请使用倒计时:ONE atomic int和ONE MRE。将int初始化为[no。的任务],启动你的任务,并使用WaitForSingleObject()/ WaitOne()等待MRE。当任务完成时,它以原子方式递减int。在任何线程上运行的任何将其递减为零的任务都会向MRE发出信号。
实际上,对X&lt; 63:)
使用此机制答案 2 :(得分:0)
可能是您的系统在WaitHandle中不能支持超过64个对象,请参见此处:
http://msdn.microsoft.com/en-us/library/z6w25xa6.aspx
您可以在此处找到此问题的解决方法:
Workaround for the WaitHandle.WaitAll 64 handle limit?
然而,正如其他答案所述,无论如何,你可能无法获得这么多线程。
答案 3 :(得分:0)
在具有4个核心或2个核心的计算机上使用这么多线程没有任何实际优势。理想情况下,您确实只需要与核心数相同的线程数。
如果你有更多,你开始失去并行性,因为线程需要上下文切换出来让其他人运行。您也可能会遇到争用问题,具体取决于算法的编写方式。
线程池的要点是告诉你的系统 maximally 使用一定数量的线程,并将剩下的线程留给系统来确定什么是最好的。