Transcript Seminar aus Softwareentwicklung
Seminar aus Softwareentwicklung
Threading unter .NET
Daniel Grünberger 9855066
Inhalt
Geschichtlicher Hintergrund Überblick über Threads Synchronisation von Daten AppDomain Literatur Inhalt
2
Geschichtlicher Hintergrund
Anfang der Softwareentwicklung verwendeten die meisten Programme „nur einen“ Prozess Software-Programme wurden immer komplexer und umfangreicher – Verwendung von mehreren Prozessen
Probleme
: welcher Prozess bekommt wie viel CPU-Leistung?
Welcher Prozess bekommt welche Ressourcen?
Viel Aufwand für Prozess-Kommunikation und nicht wirklich effizient
Lösung
: Man erschuf einen leichtgewichtigen Prozess Entstehung der Threads Geschichtlicher Hintergrund
3
Überblick über Threads
Was ist ein Thread?
Erstellen eines Threads Übergabe von Daten an Threads Überblick über Threads
4
Was ist ein Thread
Ein Thread
: bezeichnet eine selbständig ausführbare Programm-Funktion kann unabhängig vom übrigen Programm ausgeführt werden kann so dutzende von Teilaufgaben scheinbar gleichzeitig ausführen
5
Was ist ein Thread
Verwendung
Falls Programm mehrere Dinge gleichzeitig machen soll, setzt man Threads ein
Beispiel
: Berechnung der Zahl PI (3,14159265…) bis auf die Millionste Stelle genau
Ohne Thread
: Programm läuft ein paar Millionen Jahre ohne Output
Mit Thread
: Programm kann jederzeit unterbrochen werden Was ist ein Thread
6
Erstellen eines Thread
Klassen/Funktionen für Threads sind im Namensraum
System.Threading zu finden
z.B.: Start() Join() Sleep() Abort() ...
Erstellen eines Thread
7
Zustandsdiagramm
Erstellen eines Thread
8
Erstellen eines Thread
Beispiel: using System; using System.Threading; namespace ThreadHelloWorld { class ThreadHelloWorldTest { static
void
ThreadEntry() { } } Startpunkt: Funktion vom Typ void!
Neue Instanz + festlegen Console.WriteLine(“Hello Threading World”); } static void Main(string[] args) { Thread t = t.
Start
(); t.Join();
new Thread
(new ThreadStart(ThreadEntry)); t.Name = “Hello World Thread”; t.Priority = ThreadPriority.AboveNormal; des Startpunktes Optional: Name des Thread + Priorität } Starten des Thread + Warten bis beendet Erstellen eines Thread
9
Übergabe von Daten an Threads
3 Möglichkeiten Daten zu übergeben: Verwendung von globalen Variablen Kapselung des „Entrypoints“ in eine eigene Klasse Verwendung von „thread local storage“ (TLS)
10
Übergabe von Daten an Threads
Verwendung von globalen Variablen
using System; using System.Threading; namespace ThreadHelloWorldStaticInformation { class ThreadHelloWorldTest {
static
string
message
; static void ThreadEntry() { Console.WriteLine(
message
); } static void Main(string[] args) {
message
= “Hello World”; Thread t = new Thread (new ThreadStart(ThreadEntry)); t.Start(); t.Join(); } } } Thread gibt Wert der globalen Variable aus Wert der globalen Variable zuweisen
11
Übergabe von Daten an Threads
Kapselung des „Entrypoints“ in eigene Klasse
using System; using System.Threading; namespace ThreadHelloWorld {
class HelloWorld
{ private string message; public string Message { get{ return message;} set{ message = value;} } public void ThreadEntry() { Console.WriteLine(message); } } class DynamicThreadInformation { static void Main(string[] args) { HelloWorld first = new HelloWorld();
first.Message
= “Hello World”; Thread t = new Thread (new ThreadStart(first.ThreadEntry)); t.Start(); t.Join(); Eigene Klasse: Daten werden einem Property zugewiesen Instanz erstellen, Daten zuweisen und Thread starten } } } Übergabe von Daten an Threads
12
Verwendung von „thread local storage“ (TLS)
using System; using System.Threading; namespace ThreadHelloWorld { class ThreadLocalStorage { static LocalDataStoreSlot slot; static void ThreadEntry() { Console.WriteLine(“The data in the slot is: {0}”, (string)
Thread.GetData(slot)
); } static void Main(string[] args) { String message = “Hello World”; slot = Thread.AllocateDataSlot();
Thread.SetData(slot,message);
Thread t = new Thread (new ThreadStart(ThreadEntry)); t.Start(); t.Join(); } } } Daten werden von TLS ausgelsen Daten werden in TLS gestellt Übergabe von Daten an Threads
13
Synchronisation von Daten
Relativ einfache Datenübergabe an Threads Jedoch Problem bei Multithreading – falls mehrere Threads auf gleiche Daten / Ressourcen zugreifen wollen
14
Synchronisation von Daten
Multithreading - Beispiel 1(1/2)
class Worker { private int Fib(int x) { return ((x<=1)?1:(Fib(x-1)+Fib(x-2))); } } { public void doWork() } Console.WriteLine(“Thread {0} {1} {2}”, item,i,Fib(30)); Entrypoint für Thread { string item = Convert.ToString(Thread.CurrentThread.Name) + “ “; for (int i =0; i < 10; i++) } Synchronisation von Daten
15
Multithreading - Beispiel 1(2/2)
class UnsynchronizedTest { static void Main(string[] args) { Worker wq = new Worker(); Thread a = new Thread( new ThreadStart(wq.doWork)); a.Name = “a”; Thread b = new Thread( new ThreadStart(wq.doWork)); b.Name = “b”; Thread c = new Thread( new ThreadStart(wq.doWork)); c.Name = “c”; Thread d = new Thread( new ThreadStart(wq.doWork)); d.Name = “d”; Thread e = new Thread( new ThreadStart(wq.doWork)); e.Name = “e”; } } a.Start(); b.Start(); c.Start(); d.Start(); e.Start(); Threads werden nicht synchronisiert gestartet Synchronisation von Daten
16
Ergebnis?
Nicht Zufriedenstellend!!
Synchronisation von Daten
17
Warum?
Jeder Thread versucht CPU-Leistung zu bekommen Kein geordnetes vorgehen Im schlimmsten Fall kann es Threads geben, die niemals CPU-Leistung bekommen
18
Synchronisation von Daten
Allgemeine Synchronisationsprobleme
Race-Condition
: zeitlich unkoordinierte Arbeit zweier Threads gefährden den erfolgreichen Ablauf eines Programms
Deadlock
: Bei einem Deadlock warten zwei oder mehrere Threads aufeinander, und keiner kann sich aus dieser Situation befreien Bsp: Dining Philosphers,…
19
Synchronisation von Daten
Race-Condition
public void ThreadProcA(int index) { lock(GlobalList) { GlobalList.Items.RemoveAt(index); } { } public void ThreadProcB() For (int x =0; x < GlobalList.Items.Count; x++) { //… mehrere zeitaufwändige Operationen lock(GlobalList) { GlobalList.Items[x] = … // irgendeine Manipulation Löschen eines Listenelements Es kann vorkommen, dass auf leere Listenelemente zugegriffen wird - FEHLER Datenmanipulation: z.B.: Ausgabe } } } © 2003 Daniel Grünberger 9855066
20
Deadlock
public void ThreadProcA() { lock(RefA) { //… lock(RefB) { //… } } } public void ThreadProcB() { lock(RefB) { //… lock(RefA) { //… } } } Resource A wird gesperrt Wartet vergeblich auf Ressource B Resource B wird gesperrt Wartet vergeblich auf Ressource A Synchronisation von Daten
21
Gegenmaßnahmen
Funktion Monitor bzw. Lock verwenden Verhindert, dass mehrere Threads gleichzeitig auf die gleiche Ressource zugreifen Man kann Ressourcen für Threads sperren und wieder freigeben Synchronisation von Daten
22
Funktion Monitor – Lock
Monitor.Enter
(this) // kritische Ausführung Monitor.Exit
(this); Bzw.
{ try Monitor.Enter
(this); // kritische Ausführung} } { Finally Monitor.Exit
(this) } { entspricht: lock (this) //kritische Ausführung Synchronisation von Daten
23
Multithreading - Beispiel 2
public void doWork() { Monitor.Enter(this); string item = Convert.ToString(Thread.CurrentThread.Name) + “ “; for (int i =0; i < 10; i++) { Console.WriteLine(“Thread {0} {1} {2}”, item,i,Fib(30)); } Monitor.Exit(this); } Synchronisation von Daten
24
Ergebnis
Liefert das gewünschte Ergebnis Synchronisation von Daten
25
AppDomain
Was ist ein AppDomain?
Funktionsweise © 2003 Daniel Grünberger 9855066
26
Was ist ein AppDomain
Ein AppDomains kann als eine Art Prozess gesehen werden, mit dem kleinen Unterschied, das dieser weniger Ressourcen verbraucht Machen Applikation sicherer und vielseitiger Werden auch als „leichtgewichtiger“ Prozess bezeichnet
27
Was ist ein AppDomain
Was ist ein AppDomain
Jede Applikation besitzt einen Standard AppDomain und kommt auch damit aus Applikation kann aber beliebig viele AppDomains verwalten
Verwendung
: bei Verwendung von Bibliotheken die „nicht sicheren Code“ beinhalten -> in AppDomain kapseln Plug-Ins im Internet-Explorer …
28
Was ist ein AppDomain
Was ist ein AppDomain
Was ist ein AppDomain
29
Unterschiede zwischen AppDomain und einem Thread
AppDomain existiert für die Dauer der Applikation ein Thread hingegen existiert nur für eine bestimmte Zeit innerhalb eines AppDomains
30
Was ist ein AppDomain
Funktionsweise
AppDomain kann mittels der Methode
CreateDomain()
erzeugt werden
Beispiel
: … AppDomain aDomain = AppDomain.CreateDomain(“My Domain”); … ObjectHandle objHandle = aDomain.CreateInstance( “ProgCSharp”, // der Assembly Name “ProgCSharp.Shape”, False, // Typ-Name mit Namensraum // Groß-Kleinschreibung ign.
System.Reflection.BindingFlags.CreateInstance, null, // Binder new object[] {3,5}, null, null, null // Argumente // Culture // Aktivierungsattribute // Sicherheitsattribure ); … Funktionsweise
31
Funktionsweise
using System; public class MyApp { public static int main(string[] argv) { // create Domain AppDomain child = AppDomain.CreateDomain(“childapp”); // execute int r = child.ExecuteAssembly(“yourapp.exe”,null,argv); //unload domain AppDomain.Unload(child); // return result Return r; } } Funktionsweise
32
Literatur
Don Box, Chris Sells:
Essential .NET, The Common Language Runtime
, Addison-Wesley 2003 Kevin Burton: .
NET Common Language Runtime Unleashed
, Sams Publishing 2002 Dave Stutz, Ted Neward, Geoff Shilling:
Shared Source CLI Essentials
. O’Reilly 2003 Jesse Liberty:
Programming C# 2nd Edition
, O’Reilly & Associates Inc. 2002
33
Literatur
ENDE