2013-04-25 2 views
1

주 스레드에서 파일을 읽고 부분으로 분할하는 프로세스가 있습니다. 그런 다음 해당 부분은 추가 처리가 필요합니다. 다운 스트림 처리가 가능한 한 많은 CPU (또는 많은 코어)를 사용하도록 사용 가능한 스레드를 활용하고 싶습니다. 주 스레드에서 과도한 백 로그를 생성하고 싶지 않으므로 주 스레드가 다른 사용 가능한 스레드가있을 때까지 대기열에 추가 할 때까지 대기해야합니다..NET - 사용 가능한 스레드가있을 때까지 주 스레드 차단

나는 VB.NET 4.0: Looking to execute multiple threads, but wait until all threads are completed before resuming 같은 많은 문서를 참조하지만, 그들은을 완료하는 데 모든 스레드를 기다리고있다, 난 그냥

사용할 수 어떤 스레드를 필요로하는 반면 나는 Task Parallel Library 태클 수있는이 무엇인가, 아니면해야 수동으로 스레드를 만들고 스레드 풀을 모니터링합니까?

Using Reader As New StreamReader(FileName) 
    Do 
     CurrentBlockSize = Reader.ReadBlock(CurrentBuffer, 0, BufferSize) 

     RunningBuffer &= New String(CurrentBuffer) 

     If RunningBuffer.Contains(RowDelimiter) Then 
      LineParts = RunningBuffer.Split(RowDelimiter) 

      For I As Integer = 0 To LineParts.Count - 1 
       If I < LineParts.Count - 1 Then 

        'Make synchronous call that blocks until' 
        'another thread is available to process the line' 
        AddLineToTheProcessingQueue(CurrentLine) 

       Else 
        RunningBuffer = LineParts(I) 
       End If 
      Next 
     End If 

    Loop While CurrentBlockSize = BufferSize 
End Using 
+0

이것은 거의 확실하게 낭비되는 노력이며, 이러한 종류의 코드는 거의 항상 디스크 바운드입니다. 간단한 확인 : 컴퓨터를 다시 시작하고 단일 스레드 버전을 실행하십시오. 한 코어의 CPU로드가 50 %를 넘지 않으면 스레드를 더 추가하면 속도가 빨라지지 않습니다. –

+0

@HansPassant에서 다운 스트림 작업은 TCP/IP를 통해 데이터베이스에 많은 양의 데이터를 처리하고 보내는 작업을 수반 할 것입니다. TCP/IP를 통해 디스크가 읽히는 속도가 느려질 수 있습니다. 그게 내가 멀티 스레드 스레드를 원하는 부분이다 –

+0

그 다음 끌어서 데이터를 밀지 마라. 대부분의 프로그램과 마찬가지로 파일을 읽습니다. –

답변

1

이 코드를 새 콘솔 응용 프로그램에 붙여 넣으십시오.

Imports System.Threading 

Module Module1 

    ' I just picked 6 randomly, not sure what is a good strategy for picking this number 
    ' also, not sure what is the difference between a Worker Thread and a Completion thread 
    Const MaxWorkerThreads As Integer = 6 
    Const MaxCompletionPortThreads As Integer = 6 

    Sub Main() 

     ThreadPool.SetMaxThreads(MaxWorkerThreads, MaxCompletionPortThreads) 

     Dim availableWorkerThreads As Integer 
     Dim availableCompletionPortThreads As Integer 

     For i As Integer = 0 To 100 

      ' GetAvailableThreads returns results via output parameters 
      ThreadPool.GetAvailableThreads(availableWorkerThreads, availableCompletionPortThreads) 

      Dim tries As Integer = 0 

      Do While (availableWorkerThreads = 0) 
       ' this loop does not execute if there are available threads 
       ' you may want to add a fail-safe to check "tries" in case the child threads get stuck 
       tries += 1 

       Console.WriteLine(String.Format("waiting to start item {0}, attempt {1}, available threads: {2}, {3}", i, tries, availableWorkerThreads, availableCompletionPortThreads)) 

       ' failure to call Sleep will make your program unresponsive 
       Thread.Sleep(1000) 

       ' call GetAvailableThreads again for the next test at the top of the loop 
       ThreadPool.GetAvailableThreads(availableWorkerThreads, availableCompletionPortThreads) 
      Loop 

      ' this is how you pass parameters to a thread created through QueueUserWorkItem 
      Dim parameters As Object() = {i} 
      ThreadPool.QueueUserWorkItem(AddressOf DoWork, parameters) 
      ' According to MSDN, you must Sleep after calling QueueUserWorkItem, or else the current thread will just exit 
      Thread.Sleep(500) 

     Next 

    End Sub 

    Sub DoWork(parameters As Object()) 
     Dim itemNumber = parameters(0) 
     Dim sleepLength = itemNumber * 1000 
     Console.WriteLine(String.Format("Item: {0} - sleeping for {1} miliseconds.", itemNumber, sleepLength)) 
     Thread.Sleep(sleepLength) 
     Console.WriteLine(String.Format("Item: {0} - done sleeping.", itemNumber)) 
    End Sub 

End Module 
0

잘 모르겠어요 정확히 왜 이렇게 싶어하지만 BlockingCollection 또는 BoundedCapacity 세트와 흐름 블록을 사용하여 매우 비슷한 달성 할 수있다.

예를 들어 용량을 1로 설정하고 현재 사용자가 통화중인 경우 소비자 중 한 명이 현재 작업을 완료하고 해당 항목을 제거 할 때까지 대기열에 두 번째 항목을 추가 할 수 없습니다 대기열에서. 두 버전 모두 대기열에 다른 항목을 추가 할 수있을 때까지 기다리는 방법을 제공합니다.

+0

그래, 어젯밤 TPL- 데이터 흐름과 제한 용량에 대해 읽었습니다. 몇 가지 테스트를 마치면 다시보고하겠습니다. Bounded Capacity가있는 데이터 흐름 블록의 예제 코드가 있습니까? –

+0

@TomHalladay [이 테스트 세트] (https://github.com/mono/mono/blob/master/mcs/class/System.Threading.Tasks.Dataflow/Test/System.Threading.Tasks)를 볼 수 있습니다. Dataflow/BoundedCapacityTest.cs)를 모노 버전의 TDF로 만듭니다. – svick