0

I was reading a tutorial about Thread pooling in VB. There was an example with Fibonacci calculations:

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

I've start this module and it works correctly and this just handle 9 calculations:

Const FibonacciCalculations As Integer = 9

I've increase that limits, but this can just handle up to 63 calculations. From 64th calculation exception is raised that said:

waithandle must be less than 64

I would this application will handle N calculations. A good idea could be set a cap to pool of threads (for instance: 6). The N calculations will be handle using at most 6 thread at once. How could I edit the code to handle this removing the waitHandle error?

4

4 に答える 4

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
于 2013-08-07T12:36:37.230 に答える
0

システムが WaitHandle で 64 個を超えるオブジェクトをサポートできない可能性があります。こちらを参照してください。

http://msdn.microsoft.com/en-us/library/z6w25xa6.aspx

この問題の回避策は、次の場所にあります。

WaitHandle.WaitAll 64 ハンドル制限の回避策は?

ただし、他の回答が述べているように、とにかくこれだけ多くのスレッドを使用してもおそらく得はありません。

于 2013-08-07T12:18:08.650 に答える
0

4 コアまたは 2 コアのマシンで多くのスレッドを使用しても、実際の利点はありません。本当に、理想的には、コアと同じ数のスレッドのみが必要です。

それ以上ある場合は、他のスレッドを実行できるようにスレッドをコンテキスト スイッチ アウトする必要があるため、並列処理が失われ始めます。アルゴリズムの記述方法によっては、競合の問題が発生する場合もあります。

スレッドプールのポイントは、実際には、システムにいくつかのスレッドを最大限に使用し、残りをシステムに任せて最適なものを判断するように指示することです。

于 2013-08-07T12:19:26.493 に答える