Systemnahe Programmierung in C/C++ Signalbehandlung & MMap Knut Stolze stolze@informatik.uni-jena.de Lehrstuhl für Datenbanken und Informationssysteme Fakultät für Mathematik und Informatik 2006 11 29 Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 1 / 27
Agenda 1 Signale 2 Memory Mapped I/O 3 Aufgaben Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 2 / 27
Outline 1 Signale 2 Memory Mapped I/O 3 Aufgaben Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 3 / 27
Signale Asynchrone Benachrichtigung von Prozessen über Ereignisse Software Interrupt Ursachen (Beispiele) Tastendruck <ctrl>+<c> SIGINT Hardware-Exceptions Division durch 0 Zugriff auf invaliden Speicher (SIGSEGV) Prozesse senden Signale direkt Betriebssystem sendet Signale Z. B. zum Aufwecken eines Prozesses SIGPIPE beim Schreiben auf eine Pipe, die vom Leser bereits geschlossen wurde Keine weiteren Informationen (außer Signal selbst) übermittelt Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 4 / 27
Signale Asynchrone Benachrichtigung von Prozessen über Ereignisse Software Interrupt Ursachen (Beispiele) Tastendruck <ctrl>+<c> SIGINT Hardware-Exceptions Division durch 0 Zugriff auf invaliden Speicher (SIGSEGV) Prozesse senden Signale direkt Betriebssystem sendet Signale Z. B. zum Aufwecken eines Prozesses SIGPIPE beim Schreiben auf eine Pipe, die vom Leser bereits geschlossen wurde Keine weiteren Informationen (außer Signal selbst) übermittelt Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 4 / 27
Signale Asynchrone Benachrichtigung von Prozessen über Ereignisse Software Interrupt Ursachen (Beispiele) Tastendruck <ctrl>+<c> SIGINT Hardware-Exceptions Division durch 0 Zugriff auf invaliden Speicher (SIGSEGV) Prozesse senden Signale direkt Betriebssystem sendet Signale Z. B. zum Aufwecken eines Prozesses SIGPIPE beim Schreiben auf eine Pipe, die vom Leser bereits geschlossen wurde Keine weiteren Informationen (außer Signal selbst) übermittelt Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 4 / 27
Typen von Signalen 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGIO... man kill bzw. info kill Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 6 / 27
Typen von Signalen 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGIO... man kill bzw. info kill Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 6 / 27
Signal Handler Funktion, die Signal verarbeitet Aktueller Programmfluss wird unterbrochen Signal Handler wird aufgerufen Sollte nur kurze Zeit dauern Signal Handler kann potentiell wieder unterbrochen werden Programm muss transparente (reentrant) Abarbeitung der Signale gewährleisten Signal Handler muss registriert werden Mittels Funktionszeiger Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 7 / 27
Signal Handler Funktion, die Signal verarbeitet Aktueller Programmfluss wird unterbrochen Signal Handler wird aufgerufen Sollte nur kurze Zeit dauern Signal Handler kann potentiell wieder unterbrochen werden Programm muss transparente (reentrant) Abarbeitung der Signale gewährleisten Signal Handler muss registriert werden Mittels Funktionszeiger Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 7 / 27
Signal Handler Funktion, die Signal verarbeitet Aktueller Programmfluss wird unterbrochen Signal Handler wird aufgerufen Sollte nur kurze Zeit dauern Signal Handler kann potentiell wieder unterbrochen werden Programm muss transparente (reentrant) Abarbeitung der Signale gewährleisten Signal Handler muss registriert werden Mittels Funktionszeiger Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 7 / 27
Signal Handler Funktion, die Signal verarbeitet Aktueller Programmfluss wird unterbrochen Signal Handler wird aufgerufen Sollte nur kurze Zeit dauern Signal Handler kann potentiell wieder unterbrochen werden Programm muss transparente (reentrant) Abarbeitung der Signale gewährleisten Signal Handler muss registriert werden Mittels Funktionszeiger Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 7 / 27
Veraltete Schnittstelle #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); Vordefinierte Signal Handler SIG_DFL Standardfunktion (Abbruch, Coredump,... ) SIG_IGN Ignoriere Signal Probleme mit signal 1 Wie oft wird Signal Handler ausgeführt? (1x vs. immer) 2 Was passiert, wenn während der Bearbeitung eines Signals ein anderes Signal auftritt? 3 Was passiert, wenn während der Bearbeitung eines Signals dasselbe Signal nochmal auftritt? Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 9 / 27
Veraltete Schnittstelle #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); Vordefinierte Signal Handler SIG_DFL Standardfunktion (Abbruch, Coredump,... ) SIG_IGN Ignoriere Signal Probleme mit signal 1 Wie oft wird Signal Handler ausgeführt? (1x vs. immer) 2 Was passiert, wenn während der Bearbeitung eines Signals ein anderes Signal auftritt? 3 Was passiert, wenn während der Bearbeitung eines Signals dasselbe Signal nochmal auftritt? Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 9 / 27
Signal Handler Installieren #include <signal.h> int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) struct sigaction { void (*sa_handler)(int); sigset_t sa_mask; int sa_flags;... }; signum Zu bearbeitendes Signal (z. B. SIGINT) act Spezifikation des Handlers oldact Derzeit installierter Handler (wird zurückgegeben) Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 11 / 27
Signal Action sa_handler Zeiger auf Funktion, die Signal bearbeitet sa_mask Menge der Signal, die beim Abarbeiten des Handlers geblockt werden sollen sa_flags Flags SA_RESTART Starte unterbrochene Operation nach erfolgreicher Signalbearbeitung neu (z. B. Datei lesen, schreiben,... ) SA_ONESHOT Signal Handler nur einmal ausführen SA_NOMASK Signal Handler ist durch andere Signale unterbrechbar Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 12 / 27
Auslösen von Signalen Sende Signal an eigenen Prozess #include <signal.h> int raise(int sig); Sende Signal an anderen oder auch eigenen Prozess #include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig); Rechte beachten! Betriebssystem soll SIGALRM-Signal nach angegebener Zeit an eigenen Prozess senden #include <unistd.h> unsigned int alarm(unsigned int seconds); Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 14 / 27
Warten auf Signal Prozess hält so lange an (schläft), bis ein Signal eintrifft #include <unistd.h> int pause(void); Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 16 / 27
Signale in Threads Threads laufen in einem Prozess ab Signale operieren auf Prozessebene Laut POSIX reagieren alle Threads auf Signal Wenn durch Signalmaske nicht geblockt int pthread_kill(pthread_t thread, int sig) Führe Signal im Kontext des angegebenen Threads aus Signal Action (termination / stop) bezieht sich jedoch auf gesamten Prozess! Prozess (z. B. main thread muss Signal an entsprechenden Thread leiten Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 17 / 27
Outline 1 Signale 2 Memory Mapped I/O 3 Aufgaben Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 18 / 27
Memory Mapped I/O Bilde Datei auf Hauptspeicherbereich ab Arbeit auf Datei ist identisch mit regulären Speicheroperationen Betriebssystem sorgt transparent für das Schreiben der Änderungen auf Platte Effizienter als einzelne read/write-operationen Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 19 / 27
mmap void *mmap(void *addr, size_t len, int prot, int flg, int fd, off_t off); addr Vorschlag für Zieladresse Kann vom Betriebssystem angepasst werden Meist ist NULL geeignet len Größe des abzubildenden Bereichs prot Gibt an, ob Lese- (PROT_READ) und/oder Schreib- (PROT_WRITE)-Operationen erlaubt sind Zusätzlich PROT_NONE und PROT_EXEC flg Wie sollen Änderungen interpretiert werden? MAP_SHARED Schreibe Änderungen in Datei zurück MAP_PRIVATE Schreibe Änderungen nicht in Datei MAP_FIXED Interpretiere addr als exakte, nicht-änderbare Zieladresse fd Numerischer File-Deskriptor der abzubildenden Datei off Offset in die Datei Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 21 / 27
munmap & msync Entfernt Memory-Mapping einer Datei aus dem Adressraum des Prozesses int munmap(void *addr, size_t len) Zugriff auf Speicherbereich anschließend nicht mehr möglich msync wird aufgerufen Synchronisiere Hauptspeicherinhalt mit Datei int msync(void *addr, size_t len, int flags) flags MS_ASYNC Schreibe Änderungen asynchron MS_SYNC Schreibe Änderungen synchron MS_INVALIDATE Invalidiere Daten im Hauptspeicher Lies erneut von Datei Privater mmap-bereich wird nicht in Datei geschrieben Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 22 / 27
Outline 1 Signale 2 Memory Mapped I/O 3 Aufgaben Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 23 / 27
Aufgabe 1 Signale Schreiben Sie ein Programm, welches eine auf der Kommandozeile angegebene Datei öffnet, 3 Zeilen liest und auf die Standardausgabe schreibt, und anschließend auf ein SIGINT Signal wartet, bevor es den Rest der Zeilen der Datei liest und ausgibt. Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 24 / 27
Aufgabe 2 Signale Schreiben Sie ein Programm, welches einen Speicherzugriffsfehler erzeugt. Installieren Sie programmatisch einen Handler, der auf dieses Signal reagiert und auf die Standardausgabe ausgibt, welche Speicherblöcke aktuell auf dem Heap allokiert wurden. Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 25 / 27
Aufgabe 3 Memory Mapped I/O Schreiben Sie ein Programm, das eine angegebene Datei (A) öffnet und mittels memory mapped i/o den Inhalt einer zweiten Datei (B) über die Daten der ersten schreibt. Sie können die Größe des ge map ten Bereichs der Datei A selbst bestimmen, z. B. in Abhängigkeit von Datei B. Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 26 / 27
Aufgabe 4 Memory Mapped I/O + IPC Implementieren Sie die gleiche Funktionalität wie in Aufgabe 3. Jedoch soll diesmal ein Programm der Inhalt der Datei B in ein Shared Memory Segment schreiben, und das andere Programm liest von diesem Segment und schreibt die Daten (über mmap) in die Zieldatei. Knut Stolze (DBIS) C/C++ Programmierung 2006 11 29 27 / 27