Prüfungshilfe

Threads

Was ist ein Thread?

Ein Thread ist ein Teil eines Programms, der unabhängig von anderen Programmteilen oder noch nicht vorhandenen Ergebnissen ausgeführt werden kann.

Speichermodell Prozess -> Thread -> Fork

Fork() kopiert alle Daten des Prozesses (wenn aus einem Thread aufgerufen, nur alle Stammdaten und den aufrufenden Thread sowie die eltern, restliche threads im prozess werden verworfen)

Register (PC, SP, ...)
Stack
Globale Variablen
Heap
Programm Text
zum Prozess gehörende Ressourcen

Potentieller Parallelismus

  • voneinander unabhängige Aufgaben
 d.h. Resultat ist unabhängig von der Reihenfolge der Ausführung!

Wann ist es sinnvoll Threads einzusetzen?

Wen die Aufgaben unabhängig voneinander un von der Zeit / Reihenfolge Ausgeführt werden können Gründe für pot. //

  • blockender I/O
  • sich überlappender I/O
  • Asynchrone Ereignisse: Netz, Tastatur, Interrupts
  • Realtime

Was sind die Voraussetzungen, die erfüllt sein müssen?

  • Wenn unterschiedliche Ressourcen verwendet werden
  • Wenn Unabhängigkeit von Resultaten anderer Tasks besteht
 zu beachten:
 max. Konkurrenz und minimale Synchronisation
 je mehr Abhängigkeiten, um so mehr geblockte Tasks, welche aufeinander warten

In welchen typische Situationen ist ein Programm prallelisierbar?

  • Starke CPU Beanspruchung
    • kryptografische Funktionen, Matrizen, Kompression, etc.
    • während ein oder mehrere Tasks Berechnungen durchführen, kann das Programm auf I/O reagieren
    • evtl. Zuordnung einer CPU zu einer Berechnung
  • asynchrone Ereignisse
    • zufällige Intervalle zwischen Daten I/O
    • Benutzer I/O, Netzwerk Aktivität, Hardware Interrupts, Sensoren
    • Behandlungsroutinen können in einen Thread gekapselt werden unterschiedliche Behandlungsprioritäten
    • einige Aufgaben sind wichtiger
    • schnellere Reaktionszeit
    • feste Bearbeitungszeit
    • Ausführung an spezifischen Zeitpunkten
  • Beispiele für MT Apps
    • Server: Datenbanken, Fileserver, Printserver, HTTPd, P2P
    • Rechnen & Signalprocessing
    • Realtime für Server & Multitasking Apps
      • effizienter als MP
      • Scheduling
      • weniger Komplexität bei asynch. Programmen
      • Threads warten auf Ereignisse serielles Programm springt zwischen Kontexten durch Interrupts

Lebenslauf eines Threads

Anfang

Wen er mit pthread_create() erstellt wird

Ende

wenn er zur letzten anweisung im code des threads kommt oder zu einer return anweisung im Hauptcode des threads. Z.B. return(NULL)

Art (detached, joinable)

Detached: Ist losgelöst vom aifrufer Joinable: Aufrufer wartet auf beendigung

Ende des Prozesses

Wenn das ende des Main Blocks erreicht ist oder der Prozess ein kill signal vom OS bekommt.

Was ist unter Race, Deadlock und Starvation zu verstehen?

Race condition

Es wurden annahmen von Zeitlichen Abläufen im Programmcode angenommen, die zur runtime jedoch nicht bestanden. Es kann zu Abstürzen oder auch nur zu einem Fehlverhalten führen, wie zum beispiel falsche berechnungen usw.

Deadlock

Alle Threads warten auf ein Ereignis eines Threads, der befindet sich aber z.B. in einem Loop aus dem er nicht mehr herauskommt. Das Programm steht still.

Starvation

Z.B. Ein leser thread hat eine höhere priorität als der Schreiberthread auf eine mutex, der leser thread macht ein polling und verunmöglicht so den zugriff für den writer thread der eigentlich die infos abliefern möchte. Das programm steht still oder ist seeeeeeeehr langsam.

Modelle (Boss Slave, Peers, ...)

Wie sehen die Modelle aus?

Script ab Seite 38ff

Einsatzgebiete der jeweiligen Modelle

Voraussetzungen für den Einsatz, zu Beachten bei Implementation

nicht zu viel Kommunikation, nicht zu viel Teilen von Ressourcen etc.

Mix von Modellen

Buffering

Daten Austausch zwischen Threads

Weshalb?

Da man sonst Gefahr läuft, das ein writer warten muss weil er schneller ist als der reader oder umgekehrt.

Welche Punkte sind wichtig bei der Implementation (Lock, Zähler, ...)

Polling

Was ist das?

Wenn ein Thread in einer schlaufe (Timer) immer wieder nachfragt ob die Ressource frei ist oder geändert hat.

Weshalb ist das nicht gut?

Frisst CPU Time für andere Threads und macht eine grosse Last.

Wie kann man es verhindern?

Mit Condition Variables zum Beispiel.

Thread Pools

Weswegen?

Wie sieht Implementation aus?

Mutexe

  • gemeinsame Daten schützen
  • exklusiven Zugang zu Ressourcen bieten
  • Kritische Sektionen (Critical Sections)

Wie funktionieren diese?

Script Seite 73ff

Wie werden sie angewendet?

  1. jede einzelne Ressource schützen
  2. Mutex definieren
  3. lock/unlock bei Zugriff

Warum ist _trylock nicht gut?

Wen man es benutzen muss, hat man bereits im Design Fehler gemacht. Es entspricht nicht dem Konzept von Mutexen ein Polling zu machen.

Script Seite 78ff

Bedingungs-Variablen

  • Kontrolle des Zustands der Ressourcen
  • Benachrichtigungssystem

Script Seite 85ff

Einsatz

  1. warten auf Bedingung (Signal) evtl. mit Timeout
  2. Signal:
 pthread_cond_signal( &cv )
 pthread_cond_broadcast( &cv )

Wie funktionieren diese

(Wake Up? Wer wacht auf? Wer bekommt Mutex?)

  1. Priorität
  2. FIFO
 -> mit mehreren Prioritäten Starvation möglich!
  1. Broadcast - alle wachen auf und versuchen zu locken

pthread_once

Dieser code wird nur beim ersten aufrufenden thread ausgeführt für das ganze programm (z.B. initialize routines)

  • egal wieviel Mal aufgerufen -> eine einzige Ausführung wird garantiert
  • kein Thread beendet pthread_once bevor der erste pthread_once Thread beendet hat

Einsatz

wann, wie, warum?

Keys

  • Thread spezifische Daten (vergleich mit Hash Tables)
  • eine Art Pointer
  • wenn dieser Pointer von einem Thread verwendet wird, zeigt er jedes Mal auf die Threadeigenen Daten

Script Seite 100 / 115ff

Einsatz

wann, wie, warum?

Cancellation

  • Thread sollte nur an sicheren Punkten "cancellable" sein
  • Zu jedem Thread gehört ein "Cleanup Stack"

Script Seite 123ff

Typen

enabled, deferred und automatic cancellation

Bedeutung der verschiedenen Typen

Enabled: Thread cancellation ist allgemein eingeschaltet für diesen thread deferred cancelation: Thread muss zuerst einen Cancel Point erreichen (verzögerte cancellation) Automatic: Werden von pthreads gesetzt

Funktionsweise

Cleanup stacks werden aufgerufen

Cancellation Points

Automatic:

  • pthread_cond_wait
  • pthread_cond_timedwait
  • pthread_join
  • sigwait

Source code:

  • pthread_testcancel

Cleanup Stack

  • sind für "Aufräumarbeiten" da
  • werden auch bei pthread_exit ausgeführt
 pthread_cleanup_push( aufraeum_routine, (void *)argument_p )
 pthread_cleanup_pop( exec )
 1: ausführen  0: nicht ausführen
  • push muss immer ein entsprechendes pop haben: kann als Macro definiert sein
Einsatz

weshalb, wie?

Mutex Attribute

Inheritance

Ceiling

Script Seite 147ff

Priority Inversion

Signale

Script Seite 156ff

Verwendung

empfangen/Masken
darauf reagieren

fork/exec

Script Seite 175ff

wie funktioniert dies im Pthread Kontext?

fork-handlng Stacks

weshalb?
wie werden diese eingesetzt?

C

typedef

Die Programmiersprache C bietet dem Benutzer die Möglichkeit, mit dem Schlüsselwort typedef eigene Datentypen zu definieren. Die Schaffung solcher eigenen Datentypen dient dabei im Wesentlichen dazu, die Lesbarkeit der Programme zu steigern. Durch das Schlüsselwort typedef werden zunächst Synonyme erzeugt, also gleichbedeutende Datentypen. Diese Synonyme können dann genauso verwendet werden, wie die von C vorgegebenen. Am häufigsten werden selbstdefinierte Datentypen dazu verwendet, zusammengesetzte Datenstrukturen wie Arrays oder Strukturen zu bezeichnen.

Beispiel

 typedef int Ganze_Zahl;
 typedef char Zeichen;
 Ganze_Zahl a = 12;
 Zeichen b;
 b = 'e'; 

struct

Eine Struktur ist eine Folge von einem oder mehreren Elementen, die inhaltlich zusammengehören und über den Strukturnamen und den Elementnamen ansprechbar sind. In der Deklaration einer Struktur muss das Schlüsselwort struct erscheinen. Die einzelnen Elemente einer Struktur müssen nicht vom selben Typ sein, es sind auch komplexere Elemente wie Strukturen oder Arrays als Elemente einer Struktur zugelassen. Um die einzelnen Elemente anzusprechen gibt es zwei Wege. Zum einen kann ein Element über den Punkt (Bezeichner) angesprochen werden. Dazu muss der Name der Struktur und des Elementes, beide durch einen Punkt getrennt, eingegeben werden. Die andere Möglichkeit besteht darin die einzelnen Elemente über den Pfeil (Zeiger) anzusprechen. Für die Deklaration einer Struktur gibt es verschiedene Möglichkeiten. Hierbei muss zwischen Strukturmuster, das den Aufbau der Struktur angibt und keinen Speicherplatz benötigt, und der eigentlichen Struktur unterschieden werden.

Beispiel 1

 /* Ohne Strukturmuster */
 struct
 {
   char name[20];
   long verdienst;
 } akte; /* Definition einer Struktur akte */

Der Struktur wird der Name akte, über den sie dann auch angesprochen wird, zugeordnet.

Beispiel 2

 /* Strukturmuster und Struktur */
 struct AKTE
 {
   char name[20];
   long verdienst;
 };
 struct AKTE akte; /* Definition der Struktur */

Zunächst wird ein Strukturmuster mit dem Namen AKTE definiert. Durch das Strukturmuster wird kein Speicherplatz belegt; die eigentliche Zuordnung des Strukturnamens erfolgt erst in der letzten Zeile.

Pointer

Ein Pointer (Zeiger) ist ein Datentyp, bei dem Speicheradressen verwaltet werden. Eine Variable von einem Pointertyp kann also jeweils eine konkrete Speicheradresse (z.B. von einer anderen statischen Variablen) beinhalten. Pointer sind insoweit dynamisch, als sie mit ihrer Deklaration zunächst keinen weiteren Speicherplatz zugewiesen bekommen als den für die eigentliche Adresse.

referenzieren

 Datentyp *zeigervariable;

Der Datentyp des Zeigers muss vom selben Datentyp wie der sein, auf den er zeigt (referenziert).

dereferenzieren

 Zeigervariable = &variable

zurückgeben aus Funktionen

 Zeiger_Rückgabetyp *Funktionsname(Parameter)

Doppelte Pointer: wann werden diese verwendet?

  • Zum iterieren


Post new comment

The content of this field is kept private and will not be shown publicly.
  • Use <fn>...</fn> to insert automatically numbered footnotes.
  • You can use the <go> tags just like the <a> for nicer urls.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Copy the characters (respecting upper/lower case) from the image.