Ist es die richtige Implementierung?

8

Ich habe einen Windows-Dienst, der die Jobs aus der Datenbank auswählen und verarbeiten muss.

Hier ist jeder Job ein Scanvorgang, der ca. 10 Minuten dauern würde.

Ich bin sehr neu in der Task Parallel Library. Ich habe auf folgende Weise als Beispiellogik implementiert:

%Vor%

Aber das schafft viele Threads. Da die Schleife sich 100-mal wiederholt, erzeugt sie 100 Threads.

Ist es richtig, so viele parallele Threads zu erstellen?

Gibt es eine Möglichkeit, die Anzahl der Threads auf 10 (Gleichzeitigkeitslevel) zu beschränken?

    
Sai Avinash 24.06.2014, 07:12
quelle

2 Antworten

3

Ein wichtiger Faktor, der bei der Zuweisung von neuem Threads zu beachten ist, ist, dass das Betriebssystem eine Anzahl von logischen Entitäten zuweisen muss, damit dieser aktuelle Thread ausgeführt werden kann:

  1. Thread-Kernel-Objekt - ein Objekt zur Beschreibung des Threads einschließlich des Kontexts des Threads, der CPU-Register usw.
  2. Thread-Umgebungsblock - Für die Ausnahmebehandlung und lokalen Thread Speicher
  3. Benutzermodus-Stack - 1 MB Stapel
  4. Kernelmodus-Stack - Zum Übergeben von Argumenten vom Benutzermodus an den Kernel Modus

Ansonsten hängt die Anzahl der gleichzeitigen Threads , die ausgeführt werden können, von der Anzahl der Kerne ab, die Ihre Maschine packt, und das Erstellen einer Anzahl von Threads, die größer ist als die Anzahl der Kerne, die Ihre Maschine besitzt, verursacht Context Switching , die auf lange Sicht Ihre Arbeit verlangsamen können.

Also nach dem langen Intro, zu den guten Sachen. Eigentlich möchten wir die Anzahl der laufenden Threads begrenzen und sie so oft wie möglich wiederverwenden.

Für diese Art von Job würde ich mit TPL Dataflow , die auf dem Producer-Consumer -Muster basiert. Nur ein kleines Beispiel dafür, was getan werden kann:

%Vor%

Sie können jedes Block a ExecutionDataflowBlockOptions übergeben, was die Bounded Capacity (die Anzahl der Objekte im BufferBlock) und MaxDegreeOfParallelism begrenzen kann, wodurch der Block die maximale Anzahl von Nebenläufigkeiten angibt.

Es gibt ein gutes Beispiel hier , um Ihnen den Einstieg zu erleichtern .

    
Yuval Itzchakov 24.06.2014, 07:44
quelle
2

Ich bin froh, dass Sie gefragt haben, weil Sie Recht haben in dem Sinne, dass - das ist nicht der beste Ansatz.

Das Konzept von Task sollte nicht mit einem Thread verwechselt werden. Ein Thread kann mit einem Koch in einer Küche verglichen werden, während ein Task ein von einem Kunden bestelltes Gericht ist. Sie haben eine Reihe von Köchen, und sie verarbeiten die Bestellungen in einer Bestellung (in der Regel FIFO). Ein Koch beendet ein Gericht und geht dann zum nächsten über. Das Konzept des Thread-Pools ist gleich. Sie erstellen eine Reihe von Aufgaben, die abgeschlossen werden müssen, aber Sie müssen keinen neuen Aufgaben zuweisen.

Ok, also die eigentlichen Bits dazu. Es gibt ein paar. Der erste ist ThreadPoll.QueueUserWorkItem . ( Ссылка ). Unter Verwendung der Parallel-Bibliothek kann auch Parallel.For verwendet werden, es erzeugt automatisch Threads basierend auf der Anzahl der tatsächlichen CPU-Kerne, die im System verfügbar sind.

%Vor%

Beachten Sie, dass es keine Garantie gibt, dass die von Parallel.For aufgerufene Methode der Reihe nach aufgerufen wird (0,1,2,3,4,5 ...). Die tatsächliche Reihenfolge hängt von der Ausführung ab.

    
kevin 24.06.2014 07:24
quelle