Beispiel 3. Shared Memory und Explizite Synchronisation. Daniel Prokesch. 27. April 2015. Überblick. Shared Memory. Semaphore. Ressourcenverwaltung



Ähnliche Dokumente
FILE *fp; char fname[100];... fp = fopen (fname, rb ); if( fp == NULL ) { perror( fopen );... } // Fehlernachricht auf letzten Fehler, der aufkam

Systeme 1. Kapitel 6. Nebenläufigkeit und wechselseitiger Ausschluss

Softwarelösungen: Versuch 4

Tafelübung zu BS 5. Dateioperationen

Prozeß P1 Prozeß P2. Zur Synchronisation stehen den beiden Prozessen binäre Semaphore und die beiden Funktionen

Assignment #2. Virtueller Speicher Virtual Memory WS 2012/2013 IAIK 1

Bitte verwenden Sie nur dokumentenechtes Schreibmaterial!

Einführung in die Programmiersprache C

Tutorium Rechnerorganisation

Monitore. Klicken bearbeiten

Software Engineering Klassendiagramme Assoziationen

Virtueller Seminarordner Anleitung für die Dozentinnen und Dozenten

Zählen von Objekten einer bestimmten Klasse

Prof. Dr. Uwe Schmidt. 21. August Aufgaben zur Klausur Objektorientierte Programmierung im SS 2007 (IA 252)

Vorkurs C++ Programmierung

Grundlagen von Python

Linux Prinzipien und Programmierung

teamsync Kurzanleitung

Übung: Verwendung von Java-Threads

Fakultät Angewandte Informatik Lehrprofessur für Informatik

2. Hintergrundverarbeitung in Android: Services und Notifications

Tapps mit XP-Mode unter Windows 7 64 bit (V2.0)

Unterprogramme. Funktionen. Bedeutung von Funktionen in C++ Definition einer Funktion. Definition einer Prozedur

Lösung Übungszettel 6

Robotersteuerung. VL Mikrorechentechnik 2. SS 2013 Professur für Prozessleittechnik

Homogene Multi-Core-Prozessor-Architekturen

Betriebssystembau (BSB)

In diesem Tutorial lernen Sie, wie Sie einen Termin erfassen und verschiedene Einstellungen zu einem Termin vornehmen können.

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 22

Synchronisation in Java. Invisible Web

Verteilte Systeme CS5001

Outlook - CommuniGate Pro Schnittstelle installieren. Outlook - Elemente freigeben. Outlook - Freigegebene Elemente öffnen

Informatik Grundlagen, WS04, Seminar 13

Einführung in die Programmierung

KURZANLEITUNG CLOUD OBJECT STORAGE

2. Semester, 2. Prüfung, Lösung

Second Steps in eport 2.0 So ordern Sie Credits und Berichte

Java Kurs für Anfänger Einheit 5 Methoden

Modellierung und Programmierung 1

Benutzerverwaltung Business- & Company-Paket

Würfelt man dabei je genau 10 - mal eine 1, 2, 3, 4, 5 und 6, so beträgt die Anzahl. der verschiedenen Reihenfolgen, in denen man dies tun kann, 60!.

Große Übung Praktische Informatik 1

leave: mov flag, 0 ; 0 in flag speichern: Lock freigeben ret

Mit der Maus im Menü links auf den Menüpunkt 'Seiten' gehen und auf 'Erstellen klicken.

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Objektorientierte Programmierung. Kapitel 12: Interfaces

Was ist PDF? Portable Document Format, von Adobe Systems entwickelt Multiplattformfähigkeit,

iphone-kontakte zu Exchange übertragen

Virtual Private Network

KURZANLEITUNG CYBERDUCK MIT CLOUD OBJECT STORAGE

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

RAID Software. 1. Beginn

Dokumentenverwaltung. Copyright 2012 cobra computer s brainware GmbH

Über die Internetseite Hier werden unter Download/aktuelle Versionen die verschiedenen Module als zip-dateien bereitgestellt.

Tutorial: Wie kann ich Dokumente verwalten?

Tipps und Tricks zu Netop Vision und Vision Pro

Eine Anwendung mit InstantRails 1.7

Logging, Threaded Server

Adressen der BA Leipzig

Benutzerverwaltung mit Zugriffsrechteverwaltung (optional)

IntelliRestore Seedload und Notfallwiederherstellung

CA Übung Christian kann heute nicht kommen => ich bin heute da, Christian das nächste Mal wieder

Speichern. Speichern unter

Bedienungsanleitung. Stand: Copyright 2011 by GEVITAS GmbH

4D Server v12 64-bit Version BETA VERSION

Inkrementelles Backup

Prozesse. Stefan Janssen. Alexander Sczyrba

Dienstspezifikation nach RFC

Dokumentation. Black- und Whitelists. Absenderadressen auf eine Blacklist oder eine Whitelist setzen. Zugriff per Webbrowser

Outlook 2000 Thema - Archivierung

Sicherheitseinstellungen... 2 Pop-up-Fenster erlauben... 3

Inhalt. meliarts. 1. Allgemeine Informationen Administration Aufruf Das Kontextmenü Vorlagen...

SafeRun-Modus: Die Sichere Umgebung für die Ausführung von Programmen

Anleitung Typo3-Extension - Raumbuchungssystem

Einführung in die Programmierung

Workshop: Eigenes Image ohne VMware-Programme erstellen

Applet Firewall und Freigabe der Objekte

Leitfaden zur Installation von Bitbyters.WinShutdown

Software Engineering Interaktionsdiagramme

Anleitung zur Installation und Verwendung von eclipseuml 2.1.0

Lehrer: Einschreibemethoden

Programmierkurs Java

Loggen Sie sich in Ihrem teamspace Team ein, wechseln Sie bitte zur Verwaltung und klicken Sie dort auf den Punkt Synchronisation.

Dr. Monika Meiler. Inhalt

Computerarithmetik ( )

Leichte-Sprache-Bilder

Praktikum IKT 3. Semester

Berechtigungen im Kalender Anleitung für die Rechtevergabe im Outlook Kalender FHNW, Services, ICT

Formular»Fragenkatalog BIM-Server«

2. Programmierung in C

Daten am USB Stick mit TrueCrypt schützen

1 Vom Problem zum Programm

Video Unlimited -Nutzungsbeschränkungen

e-books aus der EBL-Datenbank

Ordner Berechtigung vergeben Zugriffsrechte unter Windows einrichten

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Objektbasierte Entwicklung

ICS-Addin. Benutzerhandbuch. Version: 1.0

Step by Step Webserver unter Windows Server von Christian Bartl

Transkript:

3 e 3 und Explizite Synchronisation Daniel Prokesch Institut für Technische Informatik Technische Universität Wien 27. April 2015 1

2 3 e Bisher betrachtet... Implizite Synchronisation Blockierende Lese- und Schreiboperationen Nicht-verwandte Prozesse mittels Sockets Verwandte Prozesse mittels Unnamed Pipes Heute... Datenaustasch über gemeinsamen Speicher Explizite Synchronisation von mehreren Prozessen

3 e Gemeinsamer Speicher: mehrere (verwandte sowie nicht-verwandte) Prozesse können auf selbe Region physikalischen Speichers zugreifen Gemeinsamer Speicher liegt im Adressraum der Prozesse, die den Speicher nutzen wollen Wird mit normalen Speicherzugriffsoperationen ausgelesen und verändert Schnelle Interprozesskommunikation: keine Intervention des Betriebssystemkernels 1 Explizite Synchronisation notwendig (gleichzeitiger Zugriff) 1 zero-copy, siehe http://www.linuxjournal.com/article/6345 3

4 3 e Erinnerung: mmap(2) Mapped eine Datei (file descriptor) in den Adressraum des Programms Mehrere Prozesse können auf den zugrunde liegenden Speicher zugreifen Gemeinsamer Speicher basierend auf gemeinsamer Ressource (einer Datei) shared file mapping

3 e Mapping erzeugen Erzeugen eines : mmap(2) #include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); addr Vorschlag für Startadresse, sollte NULL sein length Größe des in Bytes, oft Dateigröße (siehe fstat(2)) prot Bitmaske für Speicherschutz: PROT_NONE (kein Zugriff erlaubt), PROT_READ, PROT_WRITE flags Bitmaske, z.b. MAP_SHARED, MAP_ANONYMOUS fd Der zu mappende File Descriptor offset Offset im File (Vielfaches der Page-Größe), 0 Rückgabewert: Startadresse des (an Seitengrenze ausgerichtet), MAP_FAILED im Fehlerfall ( errno) 5

3 im virtuellen Adressraum e in unterschiedlichen Prozessen an verschiedenen Adressen erzeugt Vorsicht beim Speichern von Zeigern! (z.b. Verkettete Listen,... ) 6

7 3 Mapping Hinweise e Granularität sind Speicherseiten des Adressraums Nach Erzeugen des kann der File Descriptor geschlossen werden sind in Linux unter /proc/pid/maps gelistet Nachteil von File für gemeinsamen Speicher: Persistent Kosten für Disk I/O Für verwandte Prozesse: Gemeinsame, anonyme (MAP_SHARED MAP_ANONYMOUS) Keine zugrunde liegende Datei Mapping vor fork() erzeugt: für Kindprozess(e) im selben Adressbereich verfügbar

3 Mapping entfernen e Entfernen eines : munmap() #include <sys/mman.h> int munmap(void *addr, size_t length); Entfernt ganze Speicherseiten aus angegebenen Bereich, Startadresse muss page-aligned sein Rückgabewert: 0 bei Erfolg, sonst -1 ( errno) 8

9 3 Mapping e... char *addr = mmap(null, length, PROT_READ PROT_WRITE, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) error_exit("mmap"); if (close(fd) == -1) error_exit("close"); /* Code for working with mapped region */... if (munmap(addr, length) == -1) error_exit("munmap");

3 e Ermöglicht gemeinsamen Speicher zwischen nicht-verwandten Prozessen, ohne Datei auf Festplatte zu erzeugen memory objects über Namen identifizierbar Auf dediziertem Filesystem für flüchtigen Speicher erzeugt: tmpfs Wird wie gewöhnliches File ge-mmap-ed Vorteil: Es verhält sich wie ein richtiges Filesystem (z.b. swapping, Zugriffsrechte) Lebensdauer auf Systemlaufzeit beschränkt Teil der.1b realtime extensions Linken mit -lrt man 7 shm_overview 10

3 e API Öffnen/Erzeugen Erzeugen und Öffnen eines neuen Objekts oder Öffnen eines existierenden Objekts: shm_open(3) #include <sys/mman.h> #include <fcntl.h> /* For O_* constants */ int shm_open(const char *name, int oflag, mode_t mode); name Name der Form "/somename" oflag Bitmaske: O_RDONLY oder O_RDWR und eventuell... O_CREAT: legt Objekt an falls es nicht existiert zusätzlich O_EXCL: Fehler falls schon existiert mode Zugriffsrechte beim Erzeugen, sonst 0 Rückgabewert: File descriptor bei Erfolg, -1 im Fehlerfall ( errno) Linux: Objekt unter /dev/shm/somename erzeugt 11

12 3 e API Größe festlegen Der erzeugende Prozess legt üblicherweise die Größe (in Bytes) anhand des File Descriptors fest: ftruncate(2) #include <unistd.h> #include <sys/types.h> int ftruncate(int fd, off_t length); Rückgabewert: 0 bei Erfolg, -1 im Fehlerfall ( errno) Danach kann über den File Descriptor ein gemeinsames Mapping erzeugt (mmap(2)) und der File Descriptor geschlossen (close(2)) werden

3 e API Entfernen Einen Objektnamen entfernen: shm_unlink(3) int shm_unlink(const char *name); Name, der beim Erzeugen angegeben wurde Rückgabewert: 0 bei Erfolg, -1 im Fehlerfall ( errno) Darauffolgende shm_open() mit diesem Namen schlagen fehl (oder erzeugen neues Objekt) Der Speicher wird freigegeben, sobald der letzte Prozess das Mapping mit munmap() entfernt hat Übliche Befehle (ls, rm) zum Auflisten und Aufräumen in /dev/shm/ (z.b. bei Programmabsturz) 13

14 3 e #include <fcntl.h> #include <stdio.h> #include <sys/mman.h> #include <sys/types.h> #include <unistd.h> #define SHM_NAME "/myshm" #define MAX_DATA (50) #define PERMISSION (0600) struct myshm { unsigned int state; unsigned int data[max_data]; };

3 e int main(int argc, char **argv) { struct myshm *shared; /* create and/or open shared memory object */ int shmfd = shm_open(shm_name, O_RDWR O_CREAT, PERMISSION); if (shmfd == -1)... /* error */ /* extend (set size) */ if (ftrunctate(shmfd, sizeof *shared) == -1)... /* error */ /* map shared memory object */ shared = mmap(null, sizeof *shared, PROT_READ PROT_WRITE, MAP_SHARED, shmfd, 0); if (shared == MAP_FAILED)... /* error */ if (close(shmfd)) == -1)... /* error */ 15

3 e /* critical section entry... */ shared->data[0] = 23; printf("%d\n", shared->data[0]); /* critical section exit... */ /* unmap shared memory */ if (munmap(shared, sizeof *shared) == -1)... /* error */ /* remove shared memory object */ if (shm_unlink(shm_name) == -1)... /* error */ return 0; } /* end of main */ 16

17 3 e Synchronisation Sicherstellung von Einschränkungen nebenläufiger Prozesse In welcher Reihenfolge wird ein kritischer Abschnitt betreten: A vor B? B vor A? (Bedingungssynchronisation) Sicherstellen, dass nur genau ein Prozess auf verteilte Ressource zugreift (Wechselseitiger Ausschluss, mutual exclusion). Nicht notwendigerweise fair/abwechselnd.

3 e (1) e Thread A: a1: print "yes" Thread B: b1: print "no" Keine deterministische Abfolge von yes und no. Abhängig z.b. vom Scheduler. Mehrere Aufrufe produzieren möglicherweise Unterschiedliche Ausgaben. Weitere Ausgaben möglich? 18

19 3 e (2) e Thread A: a1: x = 5 a2: print x Thread B: b1: x = 7 Pfad zu Ausgabe 5 und am Ende x = 5? Pfad zu Ausgabe 7 und am Ende x = 7? Pfad zu Ausgabe 5 und am Ende x = 7? Pfad zu Ausgabe 7 und am Ende x = 5?

3 e (3) e Thread A: Thread B: a1: x = x + 1 b1: x = x + 1 Annahme: x ist mit 1 initialisiert. Mögliche Werte für x nach der Ausführung? Ist x++ atomic (atomar)? 20

21 3 e Grundidee Gemeinsame Variable zur Synchronisation 3 grundlegende Operationen: S = Init(N) Semaphor S mit Wert N erzeugen P(S), Wait(S), Down(S) S dekrementieren und blockieren wenn S negativ wird V(S), Post(S), Signal(S), Up(S) S inkrementieren und eventuell wartenden Prozess aufwecken

22 3 e - Serialisierung Thread A: statement a1 Thread B: statement b1 e Wie garantiert man a1 < b1 (a1 vor b1)?

3 e - Serialisierung e Initialisierung: S = Init(0) Thread A: statement a1 V(S) Thread B: P(S) statement b1 23

24 3 e - Mutex Thread A: x = x + 1 Thread B: x = x + 1 e Wie garantiert man, dass nur ein Thread in den kritischen Abschnitt eintritt?

3 e - Mutex e Initialisierung: mutex = Init(1) Thread A: P(mutex) x = x + 1 V(mutex) Thread B: P(mutex) x = x + 1 V(mutex) Kritischer Abschnitt erscheint atomar 25

3 e - Abwechselndes Arbeiten Thread A: for(;;) { x = x + 1 } Thread B: for(;;) { x = x + 1 } e Wie erreicht man, dass A und B abwechselnd arbeiten? 26

27 3 e e - Abwechselndes Arbeiten Initialisierung: S1 = Init(1) S2 = Init(0) Thread A: for(;;) { P(S1) x = x + 1 V(S2) } Thread B: for(;;) { P(S2) x = x + 1 V(S1) } 2 notwendig! Wie sieht die Synchronisation aus, wenn sich 3 Threads abwechseln sollen? N Threads?

3 e Synchronisation von Prozessen Nicht-verwandte Prozesse: Named s (Verwandte Prozesse oder Threads innerhalb eines Prozesses: Unnamed s) Ähnlich wie... Über Namen identifizierbar Auf dediziertem Filesystem für flüchtigen Speicher erzeugt: tmpfs Lebensdauer auf Systemlaufzeit beschränkt Teil der.1b realtime extensions Linken mit -pthread man 7 sem_overview Linux: Objekt unter /dev/shm/sem.somename erzeugt 28

3 e API Öffnen/Erzeugen Erzeugen und Öffnen eines neuen Semaphors oder Öffnen eines existierenden Semaphors: sem_open(3) #include <semaphore.h> #include <fcntl.h> /* For O_* constants */ /* create a new named semaphore */ sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value); /* open an existing named semaphore */ sem_t *sem_open(const char *name, int oflag); name Name der Form "/somename" oflag Bitmaske: O_CREAT, O_EXCL mode Zugriffsrechte (nur beim Erzeugen) value Initialwert (nur beim Erzeugen) Rückgabewert: Semaphoradresse bei Erfolg, im Fehlerfall SEM_FAILED ( errno) 29

3 e API Schließen/Entfernen Schließen eines Semaphors: sem_close(3) int sem_close(sem_t *sem); Entfernen eines Semaphors: sem_unlink(3) int sem_unlink(const char *name); Wird freigegeben, sobald ihn alle Prozesse geschlossen haben. Rückgabewert: 0 bei Erfolg, -1 im Fehlerfall ( errno) 30

3 e API Warten, P() Dekrementieren eines Semaphors: sem_wait(3) int sem_wait(sem_t *sem); Bei Semaphorwert > 0 kehrt die Funktion sofort zurück Sonst blockiert die Funktion bis der Wert positiv wird Rückgabewert: 0 bei Erfolg, -1 im Fehlerfall ( errno) und der Wert des Semaphors wird nicht verändert Wichtig Funktion sem_wait() kann durch ein Signal unterbrochen werden (errno == EINTR)! siehe Signalbehandlung 31

3 e API Signalisieren, V() Inkrementieren eines Semaphors: sem_post(3) int sem_post(sem_t *sem); Wenn Semaphorwert positiv wird, wird ein blockierter Prozess fortgesetzt Falls mehrere Prozesse warten: Reihenfolge ist unbestimmt (= weak semaphore) Rückgabewert: 0 bei Erfolg, -1 im Fehlerfall ( errno) und der Wert des Semaphors wird nicht verändert 32

3 e Prozess A (Code ohne Error-Handling) #include <stdio.h> #include <unistd.h> #include <semaphore.h> #include <fcntl.h> #define SEM_1 #define SEM_2 "/sem_1" "/sem_2" int main(int argc, char **argv) { sem_t *s1 = sem_open(sem_1, O_CREAT O_EXCL, 0600, 1); sem_t *s2 = sem_open(sem_2, O_CREAT O_EXCL, 0600, 0); for(int i = 0; i < 3; ++i) { sem_wait(s1); printf("critical: %s: i = %d\n", argv[0], i); sleep(1); sem_post(s2); } sem_close(s1); sem_close(s2); } return 0; 33

3 e Prozess B (Code ohne Error-Handling) #include <stdio.h> #include <unistd.h> #include <semaphore.h> #include <fcntl.h> #define SEM_1 #define SEM_2 "/sem_1" "/sem_2" int main(int argc, char **argv) { sem_t *s1 = sem_open(sem_1, 0); sem_t *s2 = sem_open(sem_2, 0); } for(int i = 0; i < 3; ++i) { sem_wait(s2); printf("critical: %s: i = %d\n", argv[0], i); sleep(1); sem_post(s1); } sem_close(s1); sem_close(s2); sem_unlink(sem_1); sem_unlink(sem_2); return 0; 34

3 e Unterbrechung durch Signale volatile sig_atomic_t want_quit = 0; int main(void) { sem_t *sem; // signal handler setup (no transparent restart), // semaphore setup... while (!want_quit) { if (sem_wait(sem) == -1) { // interrupted by system call? if (errno == EINTR) continue; error_exit(); }... if (sem_post(sem) == -1) error_exit(); } }... 35

3 e Wer legt Ressourcen an? Aufrufreihenfolge der Prozesse: fixe Reihenfolge (z.b.: Client-Server Systeme) beliebig Wer löscht Ressourcen? Fehlerfreier Programmverlauf Fehlerfall Unsynchronisiertes Aufräumen: Fehlerhafter Prozess löscht Ressourcen Synchronisiertes Aufräumen: Eigener Kommunikationskanal nötig (aufwändig) 36

3 e Ressourcenallokation... bei beliebiger Aufrufreihenfolge Anlegen, falls noch nicht existiert O_CREAT Flag ohne O_EXCL Flag z.b. : shmfd = shm_open(shm_name, O_CREAT O_RDWR, PERM); if (shmfd == -1)... /* error */ 37

3 e Ressourcenfreigabe... bei fixer Zugriffsabfolge Beim Löschen soll die Synchronisation zwischen den Prozessen sicherstellen, dass kein anderer Prozess als der Löschende mehr auf gemeinsame Ressourcen zugreift! Freigabe der selbst angelegten Ressourcen Freigabe insb. Kernel-persistenter Ressourcen bei normaler Prozessbeendigung (auch im Fehlerfall) Hilfreich: atexit(3) Registriert eine Funktion, die bei normaler Prozessbeendigung aufgerufen wird Mehrere Funktionen: in umgekehrter Reihenfolge der Registrierung Nicht bei _exit() 38

3 e Ressourcenfreigabe static int shmfd = -1; void allocate_resources(void) { shmfd = shm_open(shm_name, O_CREAT...);... } void free_resources(void) {... if (shmfd!= -1) { if (shm_unlink(shm_name) == -1) /* print error message, DON T CALL EXIT */; } } void main(void) { if (atexit(free_resources)!= 0) /* error */ } allocate_resources();... 39

3 e als schnelle Methode der IPC Explizite Synchronisation mit n Strategien zur Ressourcenallokation und -freigabe 40

41 3 Material e Linux Implementierung von /tmpfs: http://www.technovelty.org/linux/shared-memory.html Richard W. Stevens, UNIX Network Programming, Vol. 2: Interprocess Communications