Threading - inf-swe

Werbung
Threading
Arthur Zaczek
Aug 2015
Threading
1
Threading
1.1
Motivation
Threading erlaubt die gleichzeitige Ausführung von mehreren Programmteilen.
• mehrere gleichzeitige Anfragen: Webserver, Datenbank
• (zu) lange laufende Berechnungen: Scientific Computing, Spiele, User Interfaces
• mit aktuellen Multi Core Prozessoren: eigentlich überall
1.2
•
•
•
•
1.3
•
•
•
•
•
•
2
Begriffe
Prozess: Eine gestartete Anwendung im Betriebssystem
Thread: Ausführungsstrang innerhalb eines Prozesses
Multi-Processing: Abarbeitung mehrerer Aufgaben in verschiedenen Prozessen
Multi-Threading: Abarbeitung mehrerer Aufgaben in verschiedenen Threads eines Prozesses
Nachteile
hohe Komplexität
hohe Fehleranfälligkeit
erfordert oft globales Denken
Programmablauf normalerweise nicht exakt reproduzierbar
subtile Fehler können bei Entwicklung nie schlagend werden, aber immer beim Kunden
macht neue Algorithmen und Datenstrukturen notwendig
Synchronisierung
2.1
Serialisierbarkeit
Die gleichzeitige Abarbeitung aller Threads sollte das gleiche Ergebnis wie eine (beliebige)
hintereinander-Ausführung liefern.
2.2
Einfacher Fall
• Aufgaben mit minimalem Kommunikationsaufwand zwischen Threads
• Beispiele:
– Webserver für statische Seiten
– Batch-Rendering von 3D-Szenen
• Erfordert Synchronisation nur zum Abholen der Ergebnisse
2.3
Einfacher Fall - II
void Main()
{
List<Thread> threads = new List<Thread>();
// Arbeit verteilen
1
Threading
for (int i = 0; i < 4; i++)
{
threads.Add(new RenderThread(i));
threads[i].Start();
}
Bild ergebnis = new Bild(2560, 2560);
foreach (var thread in threads)
{
thread.Join();
// Teilbild schreiben
thread.SchreibeErgebnis(ergebnis);
}
}
2.4
Einfacher Fall - III
Wenn Threads nicht miteinander kommunizieren, ist das ausreichend um Serialisierbarkeit zu
garantieren
Figure 1: Serialisierbarkeit
3
Programmieren
3.1
Klasse “Thread”
Java
java.lang.Thread
CS
System.Threading.Thread
• Klasse, um neue Threads zu verwalten
• Erzeugt neuen Ausführungsfaden
2
Threading
3.2
•
•
•
•
•
•
4
Opertationen
start(): Startet einen neuen Thread
sleep(Millisekunden): Pausiert den Thread (unschön!)
join(): Warten auf das Ende eines Threads
join(Millisekunden): mit Timeout
interrupt(): signalisiert eine “Unterbrechung” an den Thread
Abort() [C#]: bricht den Thread ab
Java
4.1
Java
http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html
Zwei Wege um einen Thread zu starten:
1. Runnable implementieren
2. Thread ableiten
4.2
Runnable
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
4.3
Thread ableiten
public class HelloThread extends Thread {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new HelloThread()).start();
}
}
4.4
Kurze Demo
Java
3
Threading
4.5
C# - schnellste Variante
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(Run);
t.Start();
}
private static void Run()
{
Console.WriteLine("Hello from Thread");
}
}
4.6
C# - eigene Klasse
public class MyThread
{
private Thread thread = null;
public MyThread()
{
this.thread = new Thread(Run);
}
private void Run()
{
Console.WriteLine("Hello from Thread");
}
}
4.7
Kurze Demo
C#
4.8
Threads pausieren
Thread.sleep(ms);
• Kostet keine CPU Zeit
• ACHTUNG! Ist in vielen Situationen unelegant
• Events?
4.9
Join
t.join()
• join() wartet so lange, bis der Thread beendet wurde
• Mit einer Überladung kann man die max. Wartezeit angeben
• Dient der Synchronisierung
4
Threading
5
Threadübergreifende Kommunikation
5.1
Threadübergreifende Kommunikation
public void Transfer(Konto ziel, int betrag)
{
this.Guthaben -= betrag;
ziel.Guthaben += betrag;
}
Was könnte passieren, wenn zwei Threads gleichzeitig Transfer() auf dem
selben Konto ausführen?
5.2
Race Condition
var tmp = this.Guthaben - betragA
var tmp = this.Guthaben - betragB
this.Guthaben = tmp
this.Guthaben = tmp
Hängt das Ergebnis von der Ausführungsreihenfolge der einzelnen Berechnungsschritte ab, kann das sehr unangenehme Folgen haben
5.3
Locking mit Schlüsselwort
• Java: synchronized
• C#: lock
5.4
Java
private final static Object syncObj = new Object();
public void transfer(Konto ziel, int betrag) {
synchronized(syncObj) {
this.Guthaben -= betrag;
ziel.Guthaben += betrag;
}
}
5.5
Java 2
public synchronized void transfer(Konto ziel, int betrag) {
this.Guthaben -= betrag;
ziel.Guthaben += betrag;
}
5
Threading
In diesem Fall ungeeignet, da synchronized nur die eigene Instanz schützt,
nicht aber das Konto ziel!
5.6
CS
private readonly static object syncObj = new object();
public void Transfer(Konto ziel, int betrag)
{
lock(syncObj)
{
this.Guthaben -= betrag;
ziel.Guthaben += betrag;
}
}
5.7
Kurze Demo
1. Java, C#
2. OSPC Parallel.ForEach Auswirkung
6
Herunterladen