42
Markus Klußmann, Amjad Saadeh Institut für Informatik Pthreads Pthreads von Markus Klußmann und Amjad Saadeh

Pthreads - Freie Universität...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:

  • Upload
    others

  • View
    12

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Pthreads - Freie Universität...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:

Markus Klußmann, Amjad SaadehInstitut für Informatik

Pthreads

Pthreads

von Markus Klußmann und Amjad Saadeh

Page 2: Pthreads - Freie Universität...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:

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

Page 3: Pthreads - Freie Universität...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:

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

Page 4: Pthreads - Freie Universität...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:

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

Page 5: Pthreads - Freie Universität...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:

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

Page 6: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 6

Threads im Betriebssystem

Wie werden Threads verwaltet?

Page 7: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 7

Keine Unterstützung durch OS

Page 8: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 8

1:1 Abbildung

Page 9: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 9

m:n Abbildung

Page 10: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 10

Beispiel: Solaris

Page 11: Pthreads - Freie Universität...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:

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)

Page 12: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 12

Erzeugung und Verwaltung von Threads

Beispiel: Matrix-Multiplikation

Page 13: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 13

Erzeugung und Verwaltung von Threads

Page 14: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 14

Koordination von Threads

Wie kommunizieren Threads?

Wie vermeide ich Konsistenzkonflikte?

Wie beende ich den Trhead?

Wie vermeide ich Deadlocks?

Page 15: Pthreads - Freie Universität...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:

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;

}

Page 16: Pthreads - Freie Universität...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:

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;

}

Page 17: Pthreads - Freie Universität...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:

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

Page 18: Pthreads - Freie Universität...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:

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);

Page 19: Pthreads - Freie Universität...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:

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);

}

Page 20: Pthreads - Freie Universität...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:

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));

}

Page 21: Pthreads - Freie Universität...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:

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));

}

Page 22: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 22

Thread Scheduling

Wie kann der Programmierer das Thread-Scheduling beeinflussen?

Page 23: Pthreads - Freie Universität...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:

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

Page 24: Pthreads - Freie Universität...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:

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)

Page 25: Pthreads - Freie Universität...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:

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

Page 26: Pthreads - Freie Universität...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:

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

Page 27: Pthreads - Freie Universität...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:

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.

Page 28: Pthreads - Freie Universität...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:

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

Page 29: Pthreads - Freie Universität...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:

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

Page 30: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 30

SCS

Page 31: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 31

PCS

Page 32: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 32

Prioritätsinversion

- Probleme mit Mutexvariablen verhindern durch Anpassung der Priorität

Page 33: Pthreads - Freie Universität...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:

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)

Page 34: Pthreads - Freie Universität...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:

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)

Page 35: Pthreads - Freie Universität...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:

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

Page 36: Pthreads - Freie Universität...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:

Pthreads, 19.12.2012 36

Programmiermodelle mit Threads

Page 37: Pthreads - Freie Universität...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:

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

Page 38: Pthreads - Freie Universität...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:

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

Page 39: Pthreads - Freie Universität...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:

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

Page 40: Pthreads - Freie Universität...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:

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

Page 41: Pthreads - Freie Universität...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:

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)

Page 42: Pthreads - Freie Universität...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:

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