Pthreads - Freie Universität...int pthread_join(pthread_t thread, void **valuep)-falls kein join...
Transcript of Pthreads - Freie Universität...int pthread_join(pthread_t thread, void **valuep)-falls kein join...
Markus Klußmann, Amjad SaadehInstitut für Informatik
Pthreads
Pthreads
von Markus Klußmann und Amjad Saadeh
Pthreads, 19.12.2012 2
Inhalt
- Was sind Threads?- Prozess vs. Thread
- Kurzer Überblick POSIX- Threads im Betriebssystem- Erzeugung und Verwaltung von Threads- Koordination von Threads
- Datenverwaltung- Mutex- und Conditions-Variablen
- Thread-Scheduling- Prioritäten- Prioritätsinversion
- Programmiermodelle mit Threads- Anwendungsbeispiele
Pthreads, 19.12.2012 3
Was sind Threads?
- Übersetzung: Ausführungsfaden- teilen sich den gleichen Adressraum / Speicher- nur Ausführungsstapel privat- gehören immer zu einem Prozess- können parallel zueinander laufen- viele Implementierungen dieses Modells:
- Java-Threads- Python-Threads- Pthreads
Pthreads, 19.12.2012 4
Prozess vs. Threads
Prozess- eigener Adressraum- => privater Speicher- Daten müssen „aufwendig“ übermittelt
werden- werden immer vom Betriebssystem
verwaltet werden
Thread- gemeinsamer Adressraum- => gemeinsamer Speicher / Heap- Verwaltung übernimmt
Threadbibliothek- können aber vom Betriebssystem
unterstützt / verwaltet werden
Pthreads, 19.12.2012 5
Kurzer Überblick POSIX
- „Portable Operation System Interface“- erste Version 1988 verabschiedet (IEE Std 1003.1-1988)- aktuelle Version IEEE Std 1003.1-2008- Pthreads ab 1995- definiert u.a.:
- C-Systemaufrufe und C-Header- einige Hilfsprogramme- grundlegende I/O-Schnittstellen
- (teilweise) kompatible Betriebssysteme:- Linux (Distributionsabhängig)- Mac OS X- Windows (mit entsprechenden Erweiterungen)- Solaris
Pthreads, 19.12.2012 6
Threads im Betriebssystem
Wie werden Threads verwaltet?
Pthreads, 19.12.2012 7
Keine Unterstützung durch OS
Pthreads, 19.12.2012 8
1:1 Abbildung
Pthreads, 19.12.2012 9
m:n Abbildung
Pthreads, 19.12.2012 10
Beispiel: Solaris
Pthreads, 19.12.2012 11
Erzeugung und Verwaltung von Threads
- erzeugen durch:int pthread_create(
pthread_t *thread,const pthread_attr_t *attr,void *(*start_routine)(void *),void *arg)
- warten bis Thread beendet ist:int pthread_join(pthread_t thread, void **valuep)
- falls kein join für Thread vorliegt:int pthread_detach(pthread_t thread)
- Thread von außen abbrechen:int pthread_cancel(pthread_t thread)
Pthreads, 19.12.2012 12
Erzeugung und Verwaltung von Threads
Beispiel: Matrix-Multiplikation
Pthreads, 19.12.2012 13
Erzeugung und Verwaltung von Threads
Pthreads, 19.12.2012 14
Koordination von Threads
Wie kommunizieren Threads?
Wie vermeide ich Konsistenzkonflikte?
Wie beende ich den Trhead?
Wie vermeide ich Deadlocks?
Pthreads, 19.12.2012 15
Datenverwaltung- globale Variablen
- liegen im gemeinsamen Speicher- können Pointer auf Heap sein => gemeinsamer Speicher
int i;
void add() { i++; }
int main(int argc, char* argv[]) {
int num;
scanf(„%i“, argv[1], &num);
pthread_t threads[num];
int j;
for (j=0; j < num; j++) pthread_create(*(threads[j]));
for (j=0; j < num; j++) pthread_join(*(threads[j]));
printf(„%i\n“, i);
return;
}
Pthreads, 19.12.2012 16
DatenverwaltungSchlüssel- Schlüssel als globale Variable- jeder Thread hat eigenen Datensatz der an Schlüssel gebunden ist- sofern keine Daten von Thread gesetzt: NULL
pthread_key_t key;
void print_test() {
int* num = pthread_getspecific(key);
printf(„%i“, *num);
}
void test() {
int num = random_number;
pthread_setspecific(key, &num);
print_test();
}
int main(int argc, char* argv[]) {pthread_key_create(key);
pthread_t threads[4];int i;for (i=0; i<4; i++) pthread_create(*(threads[i]));for (i=0; i<4; i++) pthread_join(*(threads[i]));
return;
}
Pthreads, 19.12.2012 17
Mutex- und Conditionvariablen
- Synchronisation an manchen Stellen notwendig bzw. ratsam- z.B.: zwei Threads sollen die gleiche Variable manipulieren- => ein Thread sollte warten bis der andere fertig ist- Lösungen:
- Busy-Waiting- wartenden Thread blockieren
- Mutexvariablen für gegenseitigen Ausschluss- Conditionvariablen zum realisieren von Signalmechanismen
Pthreads, 19.12.2012 18
Mutex- und Conditionvariablen
Mutex:phtread_mutex_lock(&randomly_chosen_mutex);
// kritische Manipulation
pthread_mutex_unlock(&randomly_chosen_mutex);
Condition:
phtread_mutex_lock(&condition_mutex);
while (!condition) {
pthread_cond_wait(&condition_var, contition_mutex);
}
pthread_mutex_unlock(&condition_mutex);
Pthreads, 19.12.2012 19
Beispiel: Read-Write-Lock
typedef struct {
int reader;
bool writer;
pthread_mutex_t mutex;
pthread_cond_t cond;
} rw_lock;
void rw_lock_init(rw_lock *rwl) {
rwl>reader = 0;
rwl>writer = false;
pthread_cond_init(&(rwl>mutex), NULL);
pthread_mutex_init(&(rwl>cond), NULL);
}
Pthreads, 19.12.2012 20
Beispiel: Read-Write-Lock
void read_lock(rw_lock *rwl) {
pthread_mutex_lock(&(rwl>mutex));
while (rwl>writer)
pthread_cond_wait(&(rwl>cond), &(rwl>mutex));
rwl>reader++;
pthread_mutex_unlock(&(rwl>mutex));
}
void read_unlock(rw_lock *rwl) {
pthread_mutex_lock(&(rwl>mutex));
rwl>reader;
if (rwl>reader == 0)
pthread_cond_signal(&(rwl>cond));
pthread_mutex_unlock(&(rwl>mutex));
}
Pthreads, 19.12.2012 21
Beispiel: Read-Write-Lock
void write_lock(rw_lock *rwl) {
pthread_mutex_lock(&(rwl>mutex));
while ((rwl>reader > 0) || rwl>writer)
pthread_cond_wait(&(rwl>cond), &(rwl>mutex));
rwl>writer = true;
pthread_mutex_unlock($(rwl>mutex));
}
void write_unlock(rw_lock *rwl) {
pthread_mutex_unlock(&(rwl>mutex));
rwl>writer = false;
pthread_cond_broadcast($(rwl>cond));
pthread_mutex_unlock(&(rwl>mutex));
}
Pthreads, 19.12.2012 22
Thread Scheduling
Wie kann der Programmierer das Thread-Scheduling beeinflussen?
Pthreads, 19.12.2012 23
Thread Scheduling
- nur möglich, wenn POSIXTHREAD_PRIORITY_SCHEDULING Macro definiert ist
- kann zur Laufzeit festgestellt werden
- für Scheduling muss eine Datenstruktur vom Typ struct shed_param existieren
- int shed_priority (zwingend benötigt)
- Veränderung zur Laufzeit möglich
Pthreads, 19.12.2012 24
Priorität
- wie bevorzugt wird dieser Thread vom Bibliotheks-Scheduler behandelt- es gibt eine maximale Priorität (von Bibliothek vorgegeben)- es gibt eine minimale Priorität (von Bibliothek vorgegeben)
Pthreads, 19.12.2012 25
Scheduling Methoden
- SHED_FIFO (First In First Out)
- SHED_RR (Round Robbin)
- SHED_OTHER (Bibliotheksabhängig)
- kann zur Laufzeit geändert werden
Pthreads, 19.12.2012 26
SHED_FIFO (First In First Out)
- eine Warteschlange für jede Priorität
- immer der erste Thread aus Schlange höchster Priorität
- wird neuer Thread mit höherer Priorität als der aktuelle eingefügt:
→ aktuellen Thread unterbrechen und wichtigeren ausführen
Pthreads, 19.12.2012 27
SHED_RR (Round Robbin)
- CPU Zeit wird in Zeitscheiben aufgeteilt- Länge der Zeitscheiben ist von der Bibliothek vordefiniert- es wird nur die höchste Prioritätsebene betrachtet- die Prozesse in der höchsten ebene sind nacheinander an der Reiche und
können so lange rechnen wie die Zeitscheibe ist.
Pthreads, 19.12.2012 28
SHED_OTHER (Bibliotheksabhängig)
- nicht zwingend implementiert- vorhanden um sich an das Betriebssystem anpassen zu können- meist Prioritätsanpassung an I/O-Verhalten
- interaktive Threads bevorzugt- rechenintensive Threads benachteiligt
Pthreads, 19.12.2012 29
Scheduling Bereich
- gibt an welche anderen Threads beim Scheduling beachtet werden
- PTHREAD_SCOPE_PROCESS
- prozesslokales Scheduling- führt meist zu besseren Ergebnissen
- PTHREAD_SCOPE_SYSTEM
- globales Scheduling
- Kann mit pthread_attr_setscope(pthread_attr_t *attr, int scope) gesetzt werden
- Kann mit pthread_attr_getscope(pthread_attr_t *attr, int *scope) gelesen werden
Pthreads, 19.12.2012 30
SCS
Pthreads, 19.12.2012 31
PCS
Pthreads, 19.12.2012 32
Prioritätsinversion
- Probleme mit Mutexvariablen verhindern durch Anpassung der Priorität
Pthreads, 19.12.2012 33
Prioritätsinversion
- Mechanismen zur Umgehung
- Prioritäts-Obergrenze (PTHREAD_PRIO_PROTECT)
- Prioritätsvererbung (PTHREAD_PRIO_INHERIT)
- nichts (PTHREAD_PRIO_NONE)
Pthreads, 19.12.2012 34
Prioritäts-Obergrenze
- Konstante POSIX_THREAD_PRIO_PROTECT muss definiert sein
- Priorität der Obergrenze muss definiert werden- Thread der Mutexvariable sperrt bekommt die vordefiniert Priorität- zur Vermeidung von Prioritätsinversion muss diese Priorität gleich der höchsten
Priorität sein- niedriger Laufzeitaufwand- nicht fair (besonders wenn variable lange gesperrt wird)
Pthreads, 19.12.2012 35
Prioritätsvererbung
- Priorität eines Mutexinhabers wird angehoben sobald ein Thread höherer Priorität zugreifen möchte
- nach Freigabe erhält er seine ursprüngliche Priorität zurück- hoher Laufzeitaufwand- fairer, weil Priorität gleich bleibt
Pthreads, 19.12.2012 36
Programmiermodelle mit Threads
Pthreads, 19.12.2012 37
Master-Slave-Modell
- Master-Thread weist Slave-Threads Aufgaben zu
- Slave-Threads arbeiten diese ab und warten dann wieder auf Anweisungen des Master-Threads
Aufgabenverteilung
Pthreads, 19.12.2012 38
Worker-Modell
- arbeiten Aufgaben weitgehend unabhängig ab
- Worker können neue Aufgaben anlegen
- gut mit globalem Taskpool zu implementieren
Pthreads, 19.12.2012 39
Pipeline-Modell
- Aufgabe wird Stufe für Stufe abgearbeitet
- Zwischenergebnisse werden von Thread zu Thread weitergereicht
Input
Output
Stufe 1
Stufe 3
Stufe 4
Stufe 2
Pthreads, 19.12.2012 40
Client-Server-Modell
- Client-Thread stellt Anfrage an Server-Thread
- Server-Thread übergibt Ergebnis an Client zurück
- Bsp.:- GUI läuft als Client-Thread- eigentliche Berechnung
übernimmt Server-Thread
Client Server
Pthreads, 19.12.2012 41
Anwendungsbeispiele
- Server- Spiele- Video-/Bildbearbeitung- Datenkompression (pbzip)- Alle Anwendungen die größtenteils unabhängige Teilaufgaben durchführen- Livedemo: Primzahlfilter (Quellcode: http://goo.gl/kXamB)
Pthreads, 19.12.2012 42
Quellen:
http://de.wikipedia.org/wiki/Prioriätsinversion
http://pubs.opengroup.org/onlinepubs/009604599/functions/pthread_mutexattr_getprotocol.htmlhttp://pubs.opengroup.org/onlinepubs/9699919799/
Thomas Rauber, Gudula Rünger: Parallele Programmierung, Springer 2012
Margarita Esponda: OS_V8_Scheduling_Teil_2.key.pdf