Beispiel 3 - Technische Universität Wien

Beispiel 3
Überblick
Shared
Memory
Motivation
Beispiel 3
Shared Memory und Explizite Synchronisation
Memory
Mappings
POSIX Shared
Memory
Bernhard Frömel
Beispiel
Semaphore
Slides von Daniel Prokesch
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Institut für Technische Informatik
Technische Universität Wien
Beispiele
Ressourcenverwaltung
November 2015
Zusammenfassung
1
Beispiel 3
Überblick
Überblick
Shared
Memory
Bisher betrachtet. . .
I
Motivation
Implizite Synchronisation
I
Memory
Mappings
I
POSIX Shared
Memory
I
Blockierende Lese- und Schreiboperationen
Nicht-verwandte Prozesse mittels Sockets
Verwandte Prozesse mittels Unnamed Pipes
Beispiel
Semaphore
Motivation
Heute. . .
I
Datenaustasch über gemeinsamen Speicher
Synchronisationsaufgaben
I
POSIX
Semaphore
I
Beispiele
Ressourcenverwaltung
I
Memory Mappings
POSIX Shared Memory
Explizite Synchronisation von mehreren Prozessen
I
I
POSIX Semaphore
Synchronisationsaufgaben
Zusammenfassung
2
Beispiel 3
Motivation
Überblick
Shared
Memory
I
Gemeinsamer Speicher: mehrere (verwandte sowie
nicht-verwandte) Prozesse können auf selbe Region
physikalischen Speichers zugreifen
I
Gemeinsamer Speicher liegt im Adressraum der Prozesse,
die den Speicher nutzen wollen
I
Wird mit normalen Speicherzugriffsoperationen
ausgelesen und verändert
I
Schnelle Interprozesskommunikation: keine Intervention
des Betriebssystemkernels1
I
Explizite Synchronisation notwendig (gleichzeitiger
Zugriff)
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
1
„zero-copy“, siehe http://www.linuxjournal.com/article/6345
3
Beispiel 3
Memory Mappings
Erinnerung: mmap(2)
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
I
Mapped eine Datei (file descriptor) in den Adressraum des
Programms
I
Mehrere Prozesse können auf den zugrunde liegenden
Speicher zugreifen
I
Gemeinsamer Speicher basierend auf gemeinsamer
Ressource (einer Datei) → „shared file mapping“
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
4
Beispiel 3
Überblick
Mapping erzeugen
I
#include <sys/mman.h>
Shared
Memory
void *mmap(void *addr, size_t length, int prot,
int flags, int fd, off_t offset);
Motivation
Memory
Mappings
POSIX Shared
Memory
addr Vorschlag für Startadresse, sollte NULL sein
length Größe des Mappings 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
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
Erzeugen eines Mappings: mmap(2)
I
Rückgabewert: Startadresse des Mappings (an
Seitengrenze ausgerichtet), MAP_FAILED im Fehlerfall
(→ errno)
5
Beispiel 3
Mappings im virtuellen Adressraum
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
I Mappings in
unterschiedlichen Prozessen
an verschiedenen Adressen
erzeugt
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
I Vorsicht beim Speichern von
Zeigern!
(z.B. Verkettete Listen, . . . )
Beispiele
Ressourcenverwaltung
Zusammenfassung
6
Beispiel 3
Mapping Hinweise
Überblick
Shared
Memory
I
Granularität sind Speicherseiten des Adressraums
Motivation
I
Nach Erzeugen des Mappings kann der File Descriptor
geschlossen werden
I
Mappings sind in Linux unter /proc/PID/maps gelistet
I
Nachteil von File Mappings für gemeinsamen Speicher:
Persistent → Kosten für Disk I/O
I
Für verwandte Prozesse: Gemeinsame, anonyme Mappings
(MAP_SHARED | MAP_ANONYMOUS)
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
I
I
Keine zugrunde liegende Datei
Mapping vor fork() erzeugt:
→ für Kindprozess(e) im selben Adressbereich verfügbar
Zusammenfassung
7
Beispiel 3
Mapping entfernen
Überblick
Shared
Memory
Motivation
Memory
Mappings
I
Entfernen eines Mappings: munmap()
#include <sys/mman.h>
POSIX Shared
Memory
Beispiel
int munmap(void *addr, size_t length);
Semaphore
Motivation
I
Entfernt ganze Speicherseiten aus angegebenen Bereich,
Startadresse muss page-aligned sein
I
Rückgabewert: 0 bei Erfolg, sonst -1 (→ errno)
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
8
Beispiel 3
Mapping Beispiel
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
...
char *addr = mmap(NULL, length,
PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (addr == MAP_FAILED)
error_exit("mmap");
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
if (close(fd) == -1)
error_exit("close");
/* Code for working with mapped region */
...
Beispiele
Ressourcenverwaltung
if (munmap(addr, length) == -1)
error_exit("munmap");
Zusammenfassung
9
Beispiel 3
Überblick
POSIX Shared Memory
I
Ermöglicht gemeinsamen Speicher zwischen
nicht-verwandten Prozessen, ohne Datei auf Festplatte zu
erzeugen
Memory
Mappings
I
Shared memory objects über Namen identifizierbar
POSIX Shared
Memory
I
Auf dediziertem Filesystem für flüchtigen Speicher
erzeugt: tmpfs
I
Wird wie gewöhnliches File ge-mmap-ed
I
Vorteil: Es verhält sich wie ein richtiges Filesystem (z.B.
swapping, Zugriffsrechte)
I
Lebensdauer auf Systemlaufzeit beschränkt
I
Teil der POSIX.1b realtime extensions
I
Linken mit -lrt
I
man 7 shm_overview
Shared
Memory
Motivation
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
10
Beispiel 3
Shared Memory API
Öffnen/Erzeugen
Überblick
I
Shared
Memory
Motivation
Erzeugen und Öffnen eines neuen Objekts oder Öffnen
eines existierenden Objekts: shm_open(3)
#include <sys/mman.h>
#include <fcntl.h>
Memory
Mappings
POSIX Shared
Memory
/* For O_* constants */
int shm_open(const char *name, int oflag,
mode_t mode);
Beispiel
Semaphore
name Name der Form "/somename"
oflag Bitmaske: O_RDONLY oder O_RDWR und eventuell. . .
Motivation
Synchronisationsaufgaben
I
POSIX
Semaphore
I
Beispiele
Ressourcenverwaltung
Zusammenfassung
O_CREAT: legt Objekt an falls es nicht existiert
zusätzlich O_EXCL: Fehler falls schon existiert
mode Zugriffsrechte beim Erzeugen, sonst 0
I
Rückgabewert: File descriptor bei Erfolg,
-1 im Fehlerfall (→ errno)
I
Linux: Objekt unter /dev/shm/somename erzeugt
11
Beispiel 3
Shared Memory API
Größe festlegen
Überblick
Shared
Memory
I
Motivation
Memory
Mappings
Der erzeugende Prozess legt üblicherweise die Größe (in
Bytes) anhand des File Descriptors fest: ftruncate(2)
#include <unistd.h>
#include <sys/types.h>
POSIX Shared
Memory
Beispiel
int ftruncate(int fd, off_t length);
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
I
Rückgabewert: 0 bei Erfolg, -1 im Fehlerfall (→ errno)
I
Danach kann über den File Descriptor ein gemeinsames
Mapping erzeugt (mmap(2)) und der File Descriptor
geschlossen (close(2)) werden
Zusammenfassung
12
Beispiel 3
Shared Memory API
Entfernen
Überblick
Shared
Memory
Motivation
Einen Shared Memory Objektnamen entfernen:
shm_unlink(3)
Memory
Mappings
int shm_unlink(const char *name);
POSIX Shared
Memory
Beispiel
Semaphore
Motivation
I
I
Name, der beim Erzeugen angegeben wurde
I
Rückgabewert: 0 bei Erfolg, -1 im Fehlerfall (→ errno)
I
Darauffolgende shm_open() mit diesem Namen schlagen
fehl (oder erzeugen neues Objekt)
I
Der Speicher wird freigegeben, sobald der letzte Prozess
das Mapping mit munmap() entfernt hat
I
Übliche Befehle (ls, rm) zum Auflisten und Aufräumen
in /dev/shm/ (z.B. bei Programmabsturz)
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
13
Beispiel 3
Beispiel
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
#include
#include
#include
#include
#include
<fcntl.h>
<stdio.h>
<sys/mman.h>
<sys/types.h>
<unistd.h>
Beispiel
Semaphore
Motivation
#define SHM_NAME "/myshm"
#define MAX_DATA (50)
#define PERMISSION (0600)
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
struct myshm {
unsigned int state;
unsigned int data[MAX_DATA];
};
Zusammenfassung
14
Beispiel 3
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
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 */
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
/* 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
Beispiel 3
Beispiel
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
/* 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 */
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
/* remove shared memory object */
if (shm_unlink(SHM_NAME) == -1)
... /* error */
Beispiele
Ressourcenverwaltung
return 0;
} /* end of main */
Zusammenfassung
16
Beispiel 3
Synchronisation
Motivation
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
I
Sicherstellung von Einschränkungen nebenläufiger
Prozesse
I
In welcher Reihenfolge wird ein kritischer Abschnitt
betreten: A vor B? B vor A? (Bedingungssynchronisation)
I
Sicherstellen, dass nur genau ein Prozess auf verteilte
Ressource zugreift (Wechselseitiger Ausschluss, mutual
exclusion).
Nicht notwendigerweise fair/abwechselnd.
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
17
Beispiel 3
Beispiele (1)
Überblick
Shared
Memory
Motivation
Memory
Mappings
Thread A:
Thread B:
a1: print "yes"
b1: print "no"
POSIX Shared
Memory
Beispiel
I
Keine deterministische Abfolge von „yes“ und „no“.
Abhängig z.B. vom Scheduler.
I
Mehrere Aufrufe produzieren möglicherweise
Unterschiedliche Ausgaben. Weitere Ausgaben möglich?
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
18
Beispiel 3
Beispiele (2)
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Thread A:
a1: x = 5
a2: print x
Thread B:
b1: x = 7
I
Pfad zu Ausgabe „5“ und am Ende x = 5?
I
Pfad zu Ausgabe „7“ und am Ende x = 7?
Synchronisationsaufgaben
I
Pfad zu Ausgabe „5“ und am Ende x = 7?
POSIX
Semaphore
I
Pfad zu Ausgabe „7“ und am Ende x = 5?
Semaphore
Motivation
Beispiele
Ressourcenverwaltung
Zusammenfassung
19
Beispiel 3
Beispiele (3)
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Thread A:
Thread B:
a1: x = x + 1
b1: x = x + 1
I
Annahme: x ist mit 1 initialisiert. Mögliche Werte für x
nach der Ausführung?
I
Ist x++ atomic (atomar)?
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
20
Beispiel 3
Semaphore
Grundidee
Überblick
Shared
Memory
Motivation
I
„Gemeinsame Variable“ zur Synchronisation
Memory
Mappings
I
3 grundlegende Operationen:
POSIX Shared
Memory
Beispiel
I
S = Init(N)
Semaphor S mit Wert N erzeugen
I
P(S), Wait(S), Down(S)
S dekrementieren und blockieren wenn S negativ wird
I
V(S), Post(S), Signal(S), Up(S)
S inkrementieren und eventuell wartenden Prozess
aufwecken
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
21
Beispiel 3
Beispiele - Serialisierung
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Thread A:
statement a1
Thread B:
statement b1
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
Wie garantiert man a1 < b1 (a1 vor b1)?
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
22
Beispiel 3
Beispiele - Serialisierung
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Initialisierung:
S = Init(0)
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
Thread A:
statement a1
V(S)
Thread B:
P(S)
statement b1
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
23
Beispiel 3
Beispiele - Mutex
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Thread A:
x = x + 1
Thread B:
x = x + 1
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
Wie garantiert man, dass nur ein Thread in den
kritischen Abschnitt eintritt?
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
24
Beispiel 3
Beispiele - Mutex
Überblick
Shared
Memory
Motivation
Initialisierung:
mutex = Init(1)
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
Motivation
Thread A:
Thread B:
P(mutex)
x = x + 1
V(mutex)
P(mutex)
x = x + 1
V(mutex)
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
⇒ Kritischer Abschnitt erscheint atomar
Zusammenfassung
25
Beispiel 3
Beispiele - Abwechselndes Arbeiten
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Thread A:
for(;;) {
x = x + 1
}
Thread B:
for(;;) {
x = x + 1
}
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Wie erreicht man, dass A und B abwechselnd
arbeiten?
Beispiele
Ressourcenverwaltung
Zusammenfassung
26
Beispiel 3
Überblick
Shared
Memory
Beispiele - Abwechselndes Arbeiten
Initialisierung:
S1 = Init(1)
S2 = Init(0)
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
Thread A:
for(;;) {
P(S1)
x = x + 1
V(S2)
}
Thread B:
for(;;) {
P(S2)
x = x + 1
V(S1)
}
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
⇒ 2 Semaphore notwendig!
Wie sieht die Synchronisation aus, wenn sich
3 Threads abwechseln sollen? N Threads?
27
Beispiel 3
POSIX Semaphore
Überblick
Shared
Memory
I
Synchronisation von Prozessen
I
Motivation
I
Memory
Mappings
POSIX Shared
Memory
I
Ähnlich wie POSIX Shared Memory. . .
I
Beispiel
I
Semaphore
Motivation
I
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Nicht-verwandte Prozesse: Named Semaphores
(Verwandte Prozesse oder Threads innerhalb eines
Prozesses: Unnamed Semaphores)
I
Über Namen identifizierbar
Auf dediziertem Filesystem für flüchtigen Speicher
erzeugt: tmpfs
Lebensdauer auf Systemlaufzeit beschränkt
Teil der POSIX.1b realtime extensions
I
Linken mit -pthread
I
man 7 sem_overview
I
Linux: Objekt unter /dev/shm/sem.somename erzeugt
Zusammenfassung
28
Beispiel 3
Semaphore API
Öffnen/Erzeugen
Überblick
I
Shared
Memory
#include <semaphore.h>
#include <fcntl.h>
/* For O_* constants */
Motivation
Memory
Mappings
POSIX Shared
Memory
/* create a new named semaphore */
sem_t *sem_open(const char *name, int oflag,
mode_t mode, unsigned int value);
Beispiel
Semaphore
Motivation
/* open an existing named semaphore */
sem_t *sem_open(const char *name, int oflag);
Synchronisationsaufgaben
POSIX
Semaphore
name
oflag
mode
value
Beispiele
Ressourcenverwaltung
Zusammenfassung
Erzeugen und Öffnen eines neuen Semaphors oder Öffnen
eines existierenden Semaphors: sem_open(3)
I
Name der Form "/somename"
Bitmaske: O_CREAT, O_EXCL
Zugriffsrechte (nur beim Erzeugen)
Initialwert (nur beim Erzeugen)
Rückgabewert: Semaphoradresse bei Erfolg, im Fehlerfall
SEM_FAILED (→ errno)
29
Beispiel 3
Semaphore API
Schließen/Entfernen
Überblick
Shared
Memory
Motivation
I
Memory
Mappings
Schließen eines Semaphors: sem_close(3)
int sem_close(sem_t *sem);
POSIX Shared
Memory
Beispiel
I
Entfernen eines Semaphors: sem_unlink(3)
Semaphore
int sem_unlink(const char *name);
Motivation
Synchronisationsaufgaben
Wird freigegeben, sobald ihn alle Prozesse geschlossen
haben.
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
I
Rückgabewert: 0 bei Erfolg, -1 im Fehlerfall (→ errno)
Zusammenfassung
30
Beispiel 3
Semaphore API
Warten, P()
Überblick
Shared
Memory
I
int sem_wait(sem_t *sem);
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
Motivation
Dekrementieren eines Semaphors: sem_wait(3)
I
Bei Semaphorwert > 0 kehrt die Funktion sofort zurück
I
Sonst blockiert die Funktion bis der Wert positiv wird
I
Rückgabewert: 0 bei Erfolg, -1 im Fehlerfall (→ errno) und
der Wert des Semaphors wird nicht verändert
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
Wichtig
Funktion sem_wait() kann durch ein Signal
unterbrochen werden (errno == EINTR)!
→ siehe Signalbehandlung
31
Beispiel 3
Semaphore API
Signalisieren, V()
Überblick
Shared
Memory
Motivation
I
Memory
Mappings
POSIX Shared
Memory
Beispiel
int sem_post(sem_t *sem);
I
Wenn Semaphorwert positiv wird, wird ein blockierter
Prozess fortgesetzt
I
Falls mehrere Prozesse warten: Reihenfolge ist
unbestimmt (= weak semaphore)
I
Rückgabewert: 0 bei Erfolg, -1 im Fehlerfall (→ errno) und
der Wert des Semaphors wird nicht verändert
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Inkrementieren eines Semaphors: sem_post(3)
Ressourcenverwaltung
Zusammenfassung
32
Beispiel 3
Beispiel
Prozess A (Code ohne Error-Handling)
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
#include
#include
#include
#include
<stdio.h>
<unistd.h>
<semaphore.h>
<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);
Motivation
Synchronisationsaufgaben
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);
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
return 0;
}
33
Beispiel 3
Beispiel
Prozess B (Code ohne Error-Handling)
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
#include
#include
#include
#include
<stdio.h>
<unistd.h>
<semaphore.h>
<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);
Motivation
Synchronisationsaufgaben
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;
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
}
34
Beispiel 3
Beispiel
Unterbrechung durch Signale
Überblick
volatile sig_atomic_t want_quit = 0;
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
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
Beispiel 3
Ressourcenverwaltung
Überblick
Shared
Memory
Motivation
Wer legt Ressourcen an?
I
Aufrufreihenfolge der Prozesse:
I
Memory
Mappings
I
POSIX Shared
Memory
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
fixe Reihenfolge (z.B.: Client-Server Systeme)
beliebig
Wer löscht Ressourcen?
I
Fehlerfreier Programmverlauf
I
Fehlerfall
I
I
Unsynchronisiertes Aufräumen:
Fehlerhafter Prozess löscht Ressourcen
Synchronisiertes Aufräumen:
Eigener Kommunikationskanal nötig (aufwändig)
Zusammenfassung
36
Beispiel 3
Ressourcenallokation
. . . bei beliebiger Aufrufreihenfolge
Überblick
Shared
Memory
Motivation
Memory
Mappings
I
Anlegen, falls noch nicht existiert
POSIX Shared
Memory
I
O_CREAT Flag ohne O_EXCL Flag
Beispiel
I
z.B. Shared Memory:
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
shmfd = shm_open(SHM_NAME,
O_CREAT | O_RDWR, PERM);
if (shmfd == -1) ... /* error */
Beispiele
Ressourcenverwaltung
Zusammenfassung
37
Beispiel 3
Ressourcenfreigabe
. . . bei fixer Zugriffsabfolge
Überblick
Shared
Memory
Motivation
Memory
Mappings
Beim Löschen soll die Synchronisation zwischen den Prozessen
sicherstellen, dass kein anderer Prozess als der Löschende
mehr auf gemeinsame Ressourcen zugreift!
POSIX Shared
Memory
I
Freigabe der selbst angelegten Ressourcen
Beispiel
I
Freigabe insb. Kernel-persistenter Ressourcen bei
normaler Prozessbeendigung (auch im Fehlerfall)
I
Hilfreich: atexit(3)
Semaphore
Motivation
Synchronisationsaufgaben
I
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
I
I
Registriert eine Funktion, die bei normaler
Prozessbeendigung aufgerufen wird
Mehrere Funktionen: in umgekehrter Reihenfolge der
Registrierung
Nicht bei _exit()
Zusammenfassung
38
Beispiel 3
Ressourcenfreigabe
Beispiel
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
Motivation
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
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
Beispiel 3
Zusammenfassung
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
Beispiel
Semaphore
Motivation
I
Shared Memory als schnelle Methode der IPC
I
Explizite Synchronisation mit Semaphoren
I
Synchronisationsaufgaben
I
Strategien zur Ressourcenallokation und -freigabe
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
40
Beispiel 3
Material
Überblick
Shared
Memory
Motivation
Memory
Mappings
POSIX Shared
Memory
I
http://www.technovelty.org/linux/shared-memory.html
Beispiel
Semaphore
Motivation
Linux Implementierung von Shared Memory/tmpfs:
I
Richard W. Stevens, UNIX Network Programming,
Vol. 2: Interprocess Communications
Synchronisationsaufgaben
POSIX
Semaphore
Beispiele
Ressourcenverwaltung
Zusammenfassung
41