Skip to content

Commit 29d33df

Browse files
committed
Extend ThreadPool explaination
1 parent 27c2272 commit 29d33df

1 file changed

Lines changed: 79 additions & 16 deletions

File tree

23_Threads.md

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
author: Sebastian Zug, Galina Rudolf & André Dietrich
44
email: sebastian.zug@informatik.tu-freiberg.de
5-
version: 1.0.7
5+
version: 1.0.8
66
language: de
77
narrator: Deutsch Female
88
comment: Multithreading Konzepte, Thread-Modell und Interaktion, Implementierung in C#, Datenaustausch, Locking, Thread-Pool
@@ -784,40 +784,103 @@ wird durch die Nutzung von ThreadPools beschränkt, da diese als wiederverwendba
784784

785785
Die `System.Threading.ThreadPool`-Klasse stellt einer Anwendung einen Pool von "Arbeitsthreads" bereit, die vom System verwaltet werden und Ihnen die Möglichkeit bieten, sich mehr auf Anwendungsaufgaben als auf die Threadverwaltung zu konzentrieren.
786786

787+
788+
{{0-1}}
789+
********************************************************************
790+
787791
```csharp ThreadPool
788792
using System;
789793
using System.Threading;
790794

791-
class Program {
792-
// This thread procedure performs the task.
793-
static void Operate(object stateInfo)
794-
{
795-
Console.WriteLine("Hello from the thread pool.");
796-
}
795+
class Program
796+
{
797+
static void Main(string[] args)
798+
{
799+
// ThreadPool konfigurieren
800+
ThreadPool.SetMinThreads(4, 4); // Warum geben wir hier mehrere Parameter an?
801+
ThreadPool.SetMaxThreads(8, 8);
797802

798-
public static void Main(string[] args){
799-
ThreadPool.QueueUserWorkItem(Operate);
800-
//Fügt der Warteschlange eine auszuführende Methode hinzu.
801-
//Die Methode wird ausgeführt, wenn ein Thread des Threadpools verfügbar wird
802-
803-
Console.WriteLine("Main thread does some work, then sleeps.");
804-
Thread.Sleep(1000);
805-
Console.WriteLine("Main thread exits.");
806-
}
803+
Console.WriteLine("Starte mehrere Aufgaben im ThreadPool...");
804+
805+
// Kommentar 2:
806+
int taskCount = 5;
807+
CountdownEvent countdown = new CountdownEvent(taskCount);
808+
809+
for (int i = 0; i < taskCount; i++)
810+
{
811+
// Kommentar 1:
812+
// Schleifenvariable in lokale Variable kopieren sonst "Gefangene Schleifenvariable" (Closure)
813+
int taskNum = i;
814+
815+
// Lambda-Ausdruck
816+
ThreadPool.QueueUserWorkItem(state =>
817+
{
818+
Console.WriteLine($"[Task {taskNum}] gestartet auf Thread {Thread.CurrentThread.ManagedThreadId}");
819+
ThreadPool.GetAvailableThreads(out int worker, out int iocp);
820+
Console.WriteLine($"Noch frei: {worker} WorkerThreads, {iocp} IOCP-Threads");
821+
822+
// Simulierte Arbeit
823+
Thread.Sleep(500);
824+
825+
Console.WriteLine($"[Task {taskNum}] beendet");
826+
countdown.Signal();
827+
});
828+
}
829+
830+
// Zeige verfügbare Threads im Pool
831+
ThreadPool.GetAvailableThreads(out int workerThreads, out int completionPortThreads);
832+
Console.WriteLine($"Verfügbare WorkerThreads: {workerThreads}");
833+
Console.WriteLine($"Verfügbare CompletionPortThreads: {completionPortThreads}");
834+
835+
// Warten, bis Threads ihre Arbeit tun können
836+
Console.WriteLine("Main-Thread wartet auf Aufgaben...");
837+
Thread.Sleep(2000); // grobes Warten – kein sauberes Synchronisieren !!!
838+
//countdown.Wait(); // wartet, bis alle Tasks fertig
839+
Console.WriteLine("Main-Thread beendet sich.");
840+
}
807841
}
808842
```
809843
@LIA.eval(`["main.cs"]`, `mcs main.cs`, `mono main.exe`)
810844

845+
********************************************************************
846+
847+
{{1-2}}
848+
********************************************************************
849+
811850
Das klingt sehr praktisch, was aber sind die Einschränkungen?
812851

813852
+ Für die Threads können keine Namen vergeben werden, damit wird das Debugging ggf. schwieriger.
814853
+ Pooled Threads sind immer Background-Threads
815854
+ Sie können keine individuellen Prioritäten festlegen.
816855
+ Blockierte Threads im Pool senken die entsprechende Performance des Pools
817856

857+
858+
********************************************************************
859+
860+
{{2-3}}
861+
********************************************************************
862+
863+
> Wie weit kann ich mit Blick auf die Reihung eingreifen?
864+
865+
Noch mal zur Abgrenzung ...
866+
867+
```csharp StartProcess.cs
868+
using System;
869+
using System.Diagnostics;
870+
871+
class Program {
872+
static void Main() {
873+
Process.Start("notepad.exe"); // Öffnet den Windows-Editor
874+
}
875+
}
876+
```
877+
878+
... und was bedeutet das?
879+
818880
| Ebene | Wer steuert? | Beschreibung |
819881
| ------------- | -------------------- | ------------------------------------------------------------------------------- |
820882
| Prozess | Betriebssystem | CLR läuft in einem OS-Prozess |
821883
| Native Thread | Betriebssystem | `Thread`-Objekte in C# sind OS-Threads |
822884
| ThreadPool | CLR + Betriebssystem | CLR entscheidet über Ausführung im Pool; OS entscheidet über Hardware-Zuteilung |
823885

886+
********************************************************************

0 commit comments

Comments
 (0)