2. Prozesssynchronisation

Ähnliche Dokumente
Besprechung 6. Aufgabe (timed) Semaphore. Prozess 1 Prozess 2 0x Schlüssel=IPC_PRIVATE: Segment ist prozesslokal

Ganze Arrays von Semaphoren können auf einmal angelegt werden. In einer Operation können mehrere Semaphore auf einmal modifiziert werden.

Tafelübung zu BSRvS1. 3. Philosophen. Fortsetzung Grundlagen C-Programmierung

3. Philosophen. Tafelübung zu BSRvS1. Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware. Lehrstuhl für Informatik 12 TU Dortmund

Einführung in die Systemprogrammierung unter Linux

Speicherbasierte Kommunikation (T) Realisierung von Semaphoren (T) Shared Memory (P) Synchronisation mittels Semaphoren (P)

Dr. Monika Meiler. Inhalt

1 Vom Problem zum Programm

Systemprogrammierung.: unter Linux :.

Programmierung in C. Grundlagen. Stefan Kallerhoff

Einführung in die Programmierung

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

Zählen von Objekten einer bestimmten Klasse

Tafelübung zu BS 4. Speicherverwaltung

Systemprogrammierung I - Aufgaben zur Erlangung der Klausurzulassung für Informatiker und Wirtschaftsinformatiker

Einführung in die Systemprogrammierung unter Linux

Die Programmiersprache C

Betriebssysteme (BTS)

Systemnahe Programmierung in C/C++

Softwarepraktikum: Einführung in Makefiles

Einführung in die Programmierung

Einführung in die C++ Programmierung für Ingenieure

Lösungsvorschlag zum Übungsblatt 1 zur Vorlesung Informatik II / WS2001/02

critical sections und Semaphore

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2015/2016 Wirtschaftsingenieur Bachelor 5. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

Informationen zur Verwendung von Visual Studio und cmake

Einführung in die Programmierung

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Systemsoftware Praktikum Hochschule Ravensburg-Weingarten

Propädeutikum. Dipl.-Inf. Frank Güttler

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

C-Probeklausur (Informatik 1; Umfang: C, Teil 1; SS07)

PROGRAMMIEREN MIT UNIX/Linux-SYSTEMAUFRUFEN

AGROPLUS Buchhaltung. Daten-Server und Sicherheitskopie. Version vom b

7. Bewässerung: Mehrmals pro Woche

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

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

Klausur Programmieren in C Sommersemester 2007 Dipl. Biol. Franz Schenk 13. April 2007, Uhr Bearbeitungszeit: 105 Minuten

Fakultät Angewandte Informatik Lehrprofessur für Informatik

teamsync Kurzanleitung

Umzug der abfallwirtschaftlichen Nummern /Kündigung

Programmentwicklung mit C++ (unter Unix/Linux)

Modellierung und Programmierung 1

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Einführung in die C-Programmierung

Netzwerkversion PVG.view

Ingenieurinformatik Diplom-FA (C-Programmierung)

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

Hochschule Ravensburg-Weingarten Schriftliche Prüfung Programmieren Prof. Dr. M. Zeller

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Enigmail Konfiguration

Übung - Datenmigration in Windows Vista

Laborübung - Verwalten von virtuellem Speicher in Windows 7

Starten Sie Eclipse: Hier tragen sie Ihr Arbeitsverzeichnis ein. Zu Hause z.b. c:\workspace.

Aufgaben zur C-Programmierung für die Praktikumsperiode des 1.Semesters

Die Programmiersprache C99: Zusammenfassung

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

Übungspaket 31 Entwicklung eines einfachen Kellerspeiches (Stacks)

Felder, Rückblick Mehrdimensionale Felder. Programmieren in C

Einführung in die Java- Programmierung

Simplex-Umformung für Dummies

> Soft.ZIV. Maple Mathematisches Software System

Tutorium Rechnerorganisation

Anlegen eines Speicherbereichs mit DB, DW eleganter in Kombination mit EQU, Timer-Interrupt

Print2CAD 2017, 8th Generation. Netzwerkversionen

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

GS-Buchhalter/GS-Office 2015 Saldovorträge in folgenden Wirtschaftsjahren erfassen

Lineare Gleichungssysteme

Win-Digipet V 9.2 Premium Edition Wie bastele ich mir steuerbare Kontakte. Wie bastele ich mir steuerbare Kontakte? -Quick-And-Dirty-Lösung-

Erweiterung AE WWS Lite Win: AES Security Verschlüsselung

Lokales Netzwerk Wie kann ich lokal installierte Drucker im Netzwerk für andere Nutzer freigeben? Frage:

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

I N S T A L L A T I O N S A N L E I T U N G

EMC SourceOne TM für Microsoft SharePoint 7.1 Archivsuche Kurzreferenz

Übung zur Vorlesung Programmieren in C

Import und Export von Übergängern

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Anleitung zur Installation von PGP auf MacOSx

<script type="text/javascript"> <! <%= page(page.searchsuggestionsscript) %> // > </script>

Übung 9 - Lösungsvorschlag

Deklarationen in C. Prof. Dr. Margarita Esponda

Objektbasierte Entwicklung

WORKFLOW DESIGNDOKUMENT

Informatik Grundlagen, WS04, Seminar 13

Einrichten einer mehrsprachigen Webseite mit Joomla (3.3.6)

C++ Grundlagen. ++ bedeutet Erweiterung zum Ansi C Standard. Hier wird eine Funktion eingeleitet

Übersicht Programmablaufsteuerung

Objektorientierte Programmierung

Angewandte Mathematik und Programmierung

Mediator 9 - Lernprogramm

Transkript:

Tafelübung zu BSRvS1 2. Prozesssynchronisation Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware Lehrstuhl für Informatik 12 TU Dortmund olaf.spinczyk@tu-dortmund.de http://ess.cs.uni-dortmund.de/teaching/ss2008/bsrvs1/exercises/ 1

Agenda Besprechung Aufgabe 1: Wecker Fortsetzung Grundlagen C-Programmierung Aufgabe 2: Prozesssynchronisation Semaphore (sem* Funktionen) Gemeinsamer Speicher (shm* Funktionen) Makefiles Signalhandler BSRvS1: Übung 02 Prozesssynchronisation 2

Besprechung Aufgabe 1 Foliensatz Besprechung BSRvS1: Übung 02 Prozesssynchronisation 3

Grundlagen C-Programmierung Foliensatz C-Einführung BSRvS1: Übung 02 Prozesssynchronisation 4

Semaphore, semget(2) int semget(schlüssel, Anzahl, Optionen); Abfragen oder Erzeugen von Semaphoren Schlüssel = Schlüssel, der mit einer Semaphormenge im System assoziiert ist Anzahl = Anzahl der Semaphore in der Menge Optionen = IPC_CREAT, IPC_EXCL, Zugriffsrechte; mit bitweisem ODER ( ) verknüpft Semaphore werden nicht automatisch initialisiert! Rückgabewert: -1: Fehler bei der Ausführung (z.b. eine gesuchte Semaphormenge nicht gefunden), Fehlercode in errno abgelegt id: Identifier, der von den weiteren sem* Funktionen verwendet wird benötigte Header: sys/types.h, sys/ipc.h, sys/sem.h BSRvS1: Übung 02 Prozesssynchronisation 5

Semaphore, semget(2), Beispiel #include <sys/types.h> #include <sys/sem.h> #include <sys/ipc.h> #include <stdio.h> #include <errno.h> #define KEY 0xcaffee /* ein Schlüssel zur Suche nach Sem.-Mengen */ #define RIGHTS 0600 /* volle Zugriffsrechte für den Besitzer*/ int main() { int semid = 0; /* gibt es schon eine Semaphorenmenge zu diesem Schlüssel? */ semid = semget(key, 0, 0); if (semid < 0) { /* nein, also erzeuge eine Menge mit einem Semaphor... */ printf( create new semaphore\n ); semid = semget(key, 1, IPC_EXCL IPC_CREAT RIGHTS); if (semid < 0) { perror( semget ); return -1; return 0; pohl@host:~/# ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems 0xcaffee 13172741 pohl 600 1 pohl@host:~/# BSRvS1: Übung 02 Prozesssynchronisation 6

Semaphore, semctl(2) int semctl(semid, SemNr, Kommando,...); Initialisieren, Abfragen von Semaphoren Kommandos (Auswahl): SETVAL/GETVAL Setzen/Abfragen des Semaphor SemNr SETALL/GETALL Setzen/Abfragen aller Semaphore in der Menge Id IPC_RMID Freigeben einer Semaphormenge Rückgabewerte: -1: Fehler während der Ausführung, errno enthält Fehlercode >=0: je nach Kommando erwarteter Rückgabewert BSRvS1: Übung 02 Prozesssynchronisation 7

Semaphore, semctl(2) Beispiel #include <sys/types.h> #include <sys/sem.h> #include <sys/ipc.h> #include <stdio.h> #include <errno.h> #define KEY 0xcaffee /* ein Schlüssel zur Suche nach Sem.-Mengen */ int main() { int semid = 0, retval = 0; /* gibt es schon eine Semaphorenmenge zu diesem Schlüssel? */ semid = semget(key, 0, 0); if (semid > 0) { /* ja, dann initialisieren wir mit 1*/ retval = semctl(semid, 0, SETVAL, (int) 1); if (retval < 0) { perror( semctl SET ); return -1; retval = semctl(semid, 0, GETVAL); if (retval < 0) { perror( semctl GET ); return -1; printf( Semaphore hat Wert %d\n, retval); semctl(semid, 0, IPC_RMID); /* Semaphormenge entfernen */ return 0; BSRvS1: Übung 02 Prozesssynchronisation 8

Semaphore, semop(2) int semop(semid, *Operationen, AnzahlOPs); Kann eine oder mehrere Operationen auf den Semaphoren einer Semaphormenge ausführen Atomar entweder alle Operationen, oder keine! Rückgabewerte: -1: Fehler während der Ausführung, errno enthält Fehlercode 0: Ausführung erfolgreich Zentrale Struktur: struct sembuf struct sembuf { unsigned short sem_num; /* Semaphor Nr. */ short sem_op; /* Operation auf Semaphor */ short sem_flg; /* optionale Flags */ BSRvS1: Übung 02 Prozesssynchronisation 9

Semaphore, semop(2), Beispiel 3 Arten von Operationen definiert: sem_op > 0: addiere Wert von sem_op auf den aktuellen Wert des Semaphors Operation wird immer durchgeführt sem_op = 0: sog. wait-for-zero Schlafen bis Semphor = 0 sem_op < 0: Semaphor >= sem_op Operation wird direkt fortgesetzt, und sem_op vom aktuellen Wert des Semaphors abgezogen Semaphor < sem_op Operation muss warten void p() { struct sembuf sop; sop.sem_num = 0; /* Semaphor 0 */ sop.sem_flg = 0; sop.sem_op = -1; /* Dekrement */ if(semop(semid, &sop, 1) == -1) { perror( semop p ); exit(-1); void v() { struct sembuf sop; /* Semaphor 0 */ sop.sem_num = 0; sop.sem_flg = 0; sop.sem_op = 1; /* Inkrement */ if(semop(semid, &sop, 1) == -1) { perror( semop v ); exit(-1); BSRvS1: Übung 02 Prozesssynchronisation 10

Gemeinsamer Speicher 0x00000000 Prozess 1 Prozess 2 0x00000000 0x45a33b1c Shared Memory Segment 0x5516a388 0xffffffff 0xffffffff BSRvS1: Übung 02 Prozesssynchronisation 11

Gem. Speicher, shmget(2) int shmget(schlüssel, Größe, Optionen); Sehr ähnlich zu semget(2) Schlüssel = Schlüssel, der mit Shared-Memory-Segment assoziiert ist Größe = Größe des gemeinsamen Speicherbereiches Optionen = IPC_CREAT, IPC_EXCL, Zugriffsrechte; mit bitweisem ODER ( ) verknüpft Der Speicher wird nicht automatisch initialisiert! Rückgabewert: -1: Fehler bei der Ausführung (z.b. ein gesuchter gemeinsamer Speicher ist nicht verfügbar), Fehlercode in errno abgelegt id: Identifier, der von den weiteren shm* Funktionen verwendet wird benötigte Header: sys/ipc.h, sys/shm.h BSRvS1: Übung 02 Prozesssynchronisation 12

Gem. Speicher, shmget(2), Beispiel #include <sys/shm.h> #include <sys/ipc.h> #include <stdio.h> #include <errno.h> #define KEY 0xc0ffee /* ein Schlüssel für das Shared-Memory-Seg. */ #define RIGHTS 0600 /* volle Zugriffsrechte für den Besitzer*/ int main() { int shmid = 0; /* Größe, abhängig von den ausgetauschten Daten */ int size = sizeof(int[3]); /* gibt es schon den gemeinsamen Speicher? */ shmid = shmget(key, 0, 0); if (shmid < 0) { /* nein, also erzeugen wir uns einen... */ printf( create shared memory segment\n ); shmid = shmget(key, size, IPC_EXCL IPC_CREAT RIGHTS); if (shmid < 0) { perror( shmget ); return -1; return 0; pohl@host:~/# ipcs -m ------ Shared Memory Segments -------- key shmid owner perms nattach 0xc0ffee 69566495 pohl 600 0 pohl@host:~/# BSRvS1: Übung 02 Prozesssynchronisation 13

Gem. Speicher, shmctl(2) int shmctl(shmid, Operation, *Puffer); Operationen auf dem Gemeinsamen Speicher ausführen IPC_STAT: Abfrage von Statusinformationen (wird in den übergebenen Puffer vom Typ struct shmid_ds geschrieben) IPC_SET: Ändern von Nutzer/Gruppe, Berechtigungen (Daten aus Puffer) IPC_RMID: Freigeben des gemeinsamen Speichers Rückgabewerte: -1: Fehler bei der Ausführung, Fehlercode in errno >0: Abhängig von der jeweiligen Operation void shm_free() { if (shmctl(shmid, IPC_RMID, NULL) == -1) { perror( shmctl free ); exit (-1); BSRvS1: Übung 02 Prozesssynchronisation 14

Gem. Speicher, shmat(2) void *shmat(shmid, Adresse, Optionen); Gemeinsamen Speicher in den lokalen Adressraum einbinden ShmId = die von shmget zurückgelieferte Id Adresse = Adresse an der das Shared-Memory-Segment eingebunden werden soll, wenn NULL System wählt Adresse automatisch Optionen = optionale Flags benötigt zusätzlich sys/types.h Rückgabewerte: (void*) -1: Fehler bei der Ausführung, Fehlercode in errno >0: Adresse, an der das Segment eingebunden wurde BSRvS1: Übung 02 Prozesssynchronisation 15

Gem. Speicher, shmdt(2) int shmdt(adresse); Gemeinsamen Speicher aus dem lokalen Adressraum aushängen Adresse = Adresse, an der das Shared-Memory-Segment in den lokalen Adressraum eingebunden ist Rückgabewerte: -1: Fehler bei der Ausführung, Fehlercode in errno 0: Aushängen des gemeinsamen Speichers war erfolgreich BSRvS1: Übung 02 Prozesssynchronisation 16

Gem. Speicher, shm* Beispiel #include <sys/shm.h>... #define KEY 0xc0ffee /* ein Schlüssel für das Shared-Memory-Seg. */ #define RIGHTS 0600 /* volle Zugriffsrechte für den Besitzer*/ int main() { int shmid = 0, *data = NULL, size = sizeof(int[3]); shmid = shmget(key, 0, 0); if (shmid < 0) { perror( shmget ); return -1; data = (int*) shmat(shmid, NULL, 0); /* Gem. Speicher einhängen */ if (data == (void*) -1) { perror( shmat ); return -1; data[0] = 1; data[1] = 2; data[2] = 3; if (shmdt(data) == -1) { /* Gem. Speicher aushängen */ perror( shmdt ); return -1; return 0; BSRvS1: Übung 02 Prozesssynchronisation 17

Gem. Speicher, shm* Beispiel #include <sys/shm.h>... #define KEY 0xc0ffee /* ein Schlüssel für das Shared-Memory-Seg. */ #define RIGHTS 0600 /* volle Zugriffsrechte für den Besitzer*/ int main() { int shmid = 0, *data = NULL, size = sizeof(int[3]); shmid = shmget(key, 0, 0); if (shmid < 0) { perror( shmget ); return -1; data = (int*) shmat(shmid, NULL, 0); if (data == (void*) -1) { perror( shmat ); return -1; printf( data 1-3: %d, %d, %d\n, data[0], data[1], data[2]); if (shmdt(data) == -1) { perror( shmdt ); return -1; if (shmctl(shmid, 0, IPC_RMID) == -1) { /* Gem. Speicher freigeben */ perror( shmctl rm ); return -1; return 0; pohl@host:~/#./test data 1-3: 1, 2, 3 pohl@host:~/# BSRvS1: Übung 02 Prozesssynchronisation 18

Makefiles Bauen von Projekten mit mehreren Dateien Makefile Informationen wie eine Projektdatei beim Bauen des Projektes zu behandeln ist # -= Variablen =- # Name=Wert oder auch # Name+=Wert für Konkatenation CC=gcc CFLAGS=-Wall CFLAGS+=-Werror -ansi -pedantic -D_POSIX_SOURCE # -= Targets =- # Name: <benötigte Dateien und/oder andere Targets> # <TAB> Kommando # <TAB> Kommando... test_1: test_1.c test_1.h # erstes Target = Default Target $(CC) $(CFLAGS) -o test_1 test_1.c test_2: test_1 test_2.c test_2.h # test_2 braucht test_1! $(CC) $(CFLAGS) -o test_2 test_2.c clean: rm -f test_1 test_2 # Verwendung von Shell-Befehlen BSRvS1: Übung 02 Prozesssynchronisation 19

Targets & Abhängigkeiten test_1 test_2 test_1.c test_1.h test_2.c test_2.h # target test_1 test_1: test_1.c test_1.h... # target test_2 test_2: test_1 test_2.c test_2.h... Vergleich von Änderungsdatum der Quell- und Zieldateien Quelle jünger? Neu übersetzen! make durchläuft Abhängigkeitsgraph BSRvS1: Übung 02 Prozesssynchronisation 20

Makefiles und make(1) pohl@host:~/# ls Makefile test_1.c test_1.h test_2.c test_2.h pohl@host:~/# make gcc -Wall -Werror -ansi -pedantic -D_POSIX_SOURCE -o test_1 test_1.c pohl@host:~/# make clean rm -f test_1 test_2 pohl@host:~/# make test_2 gcc -Wall -Werror -ansi -pedantic -D_POSIX_SOURCE -o test_1 test_1.c gcc -Wall -Werror -ansi -pedantic -D_POSIX_SOURCE -o test_2 test_2.c pohl@host:~/# Makefiles ausführen mit make <target> bei fehlendem <target> wird das Default-Target ausgeführt Optionen -f: Makefile angeben; make -f <makefile> -j: Anzahl der gleichzeitig gestarteten Jobs; make -j 3 BSRvS1: Übung 02 Prozesssynchronisation 21

Signalhandler, sigaction(2) int sigaction(signalnr, *neueakt, *alteakt); Im eigenen Prozess Signale verarbeiten (SIGINT, SIGSTOP, etc.) Parameter SignalNr = das Signal das behandelt werden soll *neueakt = Pointer auf struct sigaction mit den Informationen zum neuen Handler (Eingabe!) *alteakt = Pointer auf struct sigaction mit den Informationen zum vorherigen Handler (Ausgabe!), ignoriert bei Übergabe von NULL Benötigt <signal.h> Rückgabewerte: -1: Fehler bei der Ausführung, Fehlercode in errno 0: Erfolgreiche Ausführung BSRvS1: Übung 02 Prozesssynchronisation 22

Signalhandler struct sigaction { void (*sa_handler)(int); /* Zeiger auf die Handler-Funktion */ sigset_t sa_mask; /* Ignoriere Signale bei Behandlung */ int sa_flags; /* Optionen */ void (*sa_restorer)(void); /* veraltet -> IGNORIEREN */ #include <signal.h>... /* die Handler-Funktion für unser Signal */ void handle_abbruch(int sig) { printf("sigint gefangen: %d!\n", SIGINT==sig); exit(2); int main() { struct sigaction action; action.sa_handler = &handle_abbruch; /* die Adresse des Handlers angeben */ sigemptyset(&action.sa_mask); /* keinerlei Signale ignorieren */ if (sigaction(sigint, &action, NULL)) { /* SIGINT Handler registrieren */ perror( sigaction ); return -1; /* Rückgabewert!= 0 => Fehler! */ while(1); return 0; BSRvS1: Übung 02 Prozesssynchronisation 23