Galileo Computing < openbook >
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung


'Wie werde ich Unix-Guru' als Buch bestellen
A. Willemer
Wie werde ich UNIX-Guru
I  ANWENDUNG
Know-How für Unix/Linux-User: Einführung, Shell, Befehle, Hilfe, Arbeit mit Dateien, Editoren, Reguläre Ausdrücke, nützliche Tools, Hardware.

II  ADMINISTRATION
Tools, Systemstart, Benutzer verwalten, Hardware konfigurieren, Software installieren, Datensicherung, Tuning, Kernel

III  NETZWERK
Client/Server Systeme, TCP/IP, Routing, IPv6, Internet-Dienste, DHCP, Webserver, Firewalls

IV  DAS X-WINDOW SYSTEM
Die grafische Oberfläche von UNIX einrichten und nutzen

V  PROGRAMMIERUNG VON SHELLSKRIPTEN
Automatisieren von Tasks durch Shell-Skripte.

VI  PERL
Interpreter, Syntax, Variablen, Steuerung, Funktionen, UNIX-Aufrufe, GUIs mit Tk

VII  PROGRAMMIERWERKZEUGE
C-Compiler, Analyse-Tools, CVS, yacc, diff

VIII  UNIX-SYSTEMAUFRUFE
UNIX-Befehle in eigenen Programmen nutzen

IX  LITERATUR
Weiterführende Literatur zu UNIX und LINUX

 
Galileo Computing / <openbook> / "Wie werde ich UNIX-Guru ?"
« Gemeinsamer Speicher: Shared Memory Prozesse Message Queues »

Unterabschnitte
  • Beispiel

Synchronisation mit Semaphoren

Semaphoren gehen auf den Informatiker E. W. Dijkstra zurück. Sie dienen als Schutz gegen gleichzeitiges Operieren in einem kritischen Bereich. Wenn beispielsweise der gemeinsame Speicher (Shared Memory) von zwei oder mehr Prozessen gleichzeitig genutzt wird, muss verhindert werden, dass sie gleichzeitig schreiben oder dass ein Prozess liest, während ein anderer Prozess schreibt.

Das Erzeugen einer Semaphore erfolgt analog zum Erzeugen des Shared Memory. Selbst die Konstante IPC_CREAT ist identisch.

#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);

Der Parameter key ist wie bei Shared Memory eine Zahl, die von den Programmen vereinbart wird, die über die Semaphore kommunizieren wollen. Im zweiten Parameter wird angegeben, wieviele Semaphoren erzeugt werden sollen.

Der letzte Parameter enthält die Berechtigung, wie man sie von chmod kennt (siehe S. chmod). Mit dieser wird die Konstante IPC_CREAT geodert, damit die Semaphore angelegt wird, falls sie noch nicht existierte. Soll der Aufruf scheitern, wenn es bereits eine solche Semaphore gibt, verknüpfen Sie auch die Konstante IPC_EXCL mit Oder.

Der Rückgabewert ist die Semaphoren-ID, die für die Identifikation benötigt wird. Scheiterte der Aufruf, gibt er -1 zurück.

Die Semaphoren werden mit dem Aufruf von semop() bearbeitet.

#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, unsigned anzahl);

Als Parameter semid wird der Rückgabewert von semget() verwendet. Der zweite Paramter nimmt die Adresse eines Array von Strukturen sembuf auf, die je eine Semaphorenoperation beschreiben. Wieviele Elemente in dem Array stehen, gibt der dritte Parameter anzahl.

Die Struktur sembuf beinhaltet die folgenden Felder:

struct sembuf {
    short sem_num;  /* semaphore number: 0 = first */
    short sem_op;   /* semaphore operation */
    short sem_flg;  /* operation flags */
};

sem_num gibt an, welche Semaphore des Semaphorensets gemeint ist. Die Zählung beginnt bei 0. sem_flag kann die Optionen IPC_NOWAIT und SEM_UNDO annehmen. SEM_UNDO bewirkt, dass die Operation bei Ende des Prozesses zurückgenommen wird.

Der Systemaufruf semop() gewährleistet, dass die Operationen nur durchgeführt werden, wenn alle Operationen gelingen.

Die Variable sem_op der Struktur sembuf bestimmt die Operation.

  • [semop>0]
    Der Wert der Semaphore wird um den Wert von semop erhöht. Diese Operation blockiert nie.
  • [semop==0]
    Wenn der Wert der Semaphore (semval) Null ist, läuft die Operation durch. Ansonsten blockiert der Prozess, bis die Semaphore Null wird.
  • [semop<0]
    Der Wert der Semaphore wird um den Wert von semop verringert, sofern die Semaphore durch diese Operation nicht negativ wird. Ist semop größer als der Wert der Semaphore, schläft der Prozess bis der Wert hoch genug ist.

#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int kommando,
           union semun arg);

Der Parameter kommando gibt an, welche Operation ausgeführt wird. Das wichtigste Kommando ist IPC_RMID. Es zerstört sofort alle Semaphoren dieses Semaphorensets. Die auf die Semaphoren wartenden Prozesse werden geweckt und erhalten einen Fehler als Rückgabewert ihres Funktionsaufrufs.

Beispiel

Das Programm sem erzeugt eine Semaphore, sofern nicht schon eine existiert, und wartet auf die Returntaste. Anschließend setzt sie die Semaphore. Das führt zum Blockieren oder das Programm betritt den kritischen Bereich. Das wird am Bildschirm angezeigt. Nach erneutem Drücken der Returntaste verlässt das Programm wieder den kritischen Bereich und gibt ihn für andere frei. Zum Testen können Sie das Programm auf mehreren Terminals oder Fenstern starten und sie nacheinander in den kritischen Bereich gehen lassen.

[Semaphoren sem.c]
#include <sys/ipc.h>
#include <sys/sem.h>

int main(int argc, char **argv)
{
int semID;
struct sembuf sema;

/* Semaphore erzeugen */
    semID = semget(2404, 1, IPC_CREAT | 0666);
    if (semID >= 0) {
        puts("Semaphore erzeugt. Vor Anfrage");
        getchar();
        /* Bereite die Semaphore vor und starte */
        sema.sem_num = 0;
        sema.sem_flg = SEM_UNDO;
        sema.sem_op  = -1;
        if (-1==semop(semID, &sema, 1)) {
            /* Fehler */
            perror("semop");
        }
        puts("bin im kritischen Bereich");
        getchar();
        sema.sem_op  = 1;
        if (-1==semop(semID, &sema, 1)) {
            /* Fehler */
            perror("semop");
        }
        puts("und nun wieder draußen");
    } else {
        perror("semget");
    }
}

Auch die Semaphore bleibt nach Verlassen des Programms bestehen und muss explizit gelöscht werden. Dazu reicht das folgende Programmbeispiel aus:

[Semaphoren destroy.c]
#include <sys/ipc.h>
#include <sys/shm.h>

int main(int argc, char **argv)
{
int semID;
char *myPtr;
int i;

semID = semget(2404, 1, 0666);
    if (semID >= 0) {
        /* zerstöre die Semaphore */
        semctl(semID, 1, IPC_RMID, 0);
    } else { /* semctl lief schief */
        perror("semget");
    }
}

Die Semaphore bleibt solange erhalten, bis ein Programm in explizit entfernt (s. o.), bis zum nächsten Shutdown oder bis er mit dem Befehl ipcrm sem explizit gelöscht wird (siehe S. ipcrm).



« Gemeinsamer Speicher: Shared Memory | Prozesse | Message Queues »
 
 Zum Katalog
Zum Katalog
Wie werde ich UNIX-Guru?
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 UNIX/Linux

PHP 4-Workshop

Einstieg in Python

Perl fürs Web

MySQL 4

GNOME 2.0
 Empfehlung

Einstieg in XML
 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
Info

 MyGalileo
Der Service für registrierte Leser:
Zu MyGalileo
Info



Copyright © Galileo Press GmbH 2003
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.
[Galileo Computing]

Galileo Press GmbH, Gartenstraße 24, 53229 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de