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 ?"
« Synchronisation mit Semaphoren Prozesse Leichtgewichtsprozesse: Threads »

Unterabschnitte
  • Beispiel

Message Queues

Message Queues dienen zum Senden und Empfangen von Nachrichten. Eine solche Nachrichtenschlange kann mit Nachrichten verschiedenen Typs umgehen. Der Typ wird durch die Anwendung bestimmt und ist einfach eine Zahl. Ein Prozess kann Nachrichten an die Warteschlange senden. Beim Erreichen der Kapazität der Schlange kann der Prozess per Parameter bestimmen, ob er blockieren will bis die Nachricht abzuliefern ist oder lieber mit einem Fehler zurückkehren möchte. Auf der anderen Seite kann ein Prozess eine Nachricht bestimmten Typs anfordern. Auch hier steht es dem Programmierer frei, ob er möchte, dass der Prozess wartet, bis er eine passende Nachricht bekommt oder ob er mit einer Fehlermeldung sofort zurückkehren soll.

Die Funktion msgget() legt eine Message Queue an.

#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);

Der Parameter key ist entweder eine Schlüsselzahl oder IPC_PRIVATE. Der Parameter msgflg kombiniert die Konstanten IPC_CREAT und IPC_EXCL und neun Berechtigungsbits für den Eigner, die Gruppe und der Welt, wie sie von chmod verwendet werden, indem sie mit dem senkrechten Strich geodert werden.

Der Rückgabewert ist -1 im Fehlerfall oder die Message Queue ID, die für die nächsten Aufrufe benötigt wird.

Die Funktionen msgsnd() und msgrcv() verwenden eine Struktur msgbuf für ihre Nachrichten, die den Typ und den Puffer enthält.

struct msgbuf {
    long mtype;     /* von der Anwendung definierbar > 0 */
    char mtext[1];  /* Nachrichtendaten beginnen hier */
};

Es kann als Typ eine beliebige Zahl größer Null verwendet werden, die allein von der Applikation festgelegt werden. Auf diese Weise können Sie leicht verschiedene Arten von Daten austauschen und sie über den Nachrichtentyp trennen. Für die eigenen Nachrichten werden Sie im mtext vermutlich mehr als ein Zeichen versenden wollen. Dazu definieren Sie sich eine eigene Struktur mit entsprechend größerem Datenpuffer. Die Größe wird beiden Funktionen als Parameter übergeben.

Mit der Funktion msgsnd() werden Nachrichten versandt.

#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, struct  msgbuf  *msgp,  size_t msgsz, 
           int msgflg);

Der erste Parameter ist der Rückgabewert der Funktion msgget(). Es folgt die Adresse der Datenstruktur mit dem Nachrichtentyp und den Daten. Der Parameter msgsz ist so groß wie das Array mtext in der Datenstruktur für die Nachricht. msgflg kann mit der Optionen IPC_NOWAIT besetzt werden. Dann wird die Funktion bei einer übervollen Message Queue nicht blockieren und warten, bis wieder Platz ist, sondern mit einem Fehler zurückkehren.

Mit der Funktion msgrcv() werden werden Nachrichten empfangen.

#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv(int msqid, struct  msgbuf  *msgp,  size_t msgsz, 
           long msgtyp, int msgflg);

Der erste Parameter ist der Rückgabewert der Funktion msgget(). Es folgt die Adresse der Datenstruktur, in der sich nach erfolgreichem Empfang der Nachrichtentyp und die Daten wiederfinden. Der Parameter msgsz ist so groß wie das Array mtext in der Datenstruktur für die Nachricht. Im Parameter msgtyp kann festgelegt werden, auf welchen Nachrichtentyp msgrcv() warten soll. Alle anderen Typen werden von msgrcv() ignoriert. Wird als Parameter hier 0 angegeben, nimmt mgsrcv() jeden Typ entgegen. msgflg kann mit der Optionen IPC_NOWAIT besetzt werden. Dann wird die Funktion nicht blockieren und warten, bis eine Nachricht vorliegt, sondern bei leerer Message Queue mit einem Fehler zurückkehren.

Mit der Funktion msgctl() werden bestimmte Eigenschaften der Nachrichten verwaltet.

#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid, int kommando, struct msqid_ds *buf);

Als Paramter kommando können folgende Konstanten übergeben werden:

[Message Kontrollkommandos]L|L Konstante & Bedeutung
IPC_STAT & Die Informationen über die Message Queue einlesen
IPC_SET & Ändere die Benutzerrechte in mode
IPC_RMID & Zerstört die Message Queue und weckt alle darauf wartenden Prozesse

Mit dem Kommando ipcs bekommen Sie einen Überblick über die angeforderten Message Queues.

Beispiel

Das Programm rcvmsg.c wartet auf eine Nachricht in einer Message Queue. Die Nummer des Typs wird als erster Parameter beim Aufruf übergeben. Wird nichts übergeben wartet das Programm auf eine beliebige Nachricht.

[Empfange Nachricht rcvmsg.c]
#include <sys/ipc.h>
#include <sys/msg.h>

#define MSGSIZE 20

int main(int argc, char **argv)
{
int msgID;
struct myMsg {
  long mtype;
  char mtext[MSGSIZE];
} dataMsg;
long msgTyp = 0;

/* hole die Messagetypnummer aus dem ersten Parameter */
    if (argc>1) {
        msgTyp = atol(argv[1]);
    }

/* Messagequeue oeffnen bzw. erzeugen */
    msgID = msgget(2404, IPC_CREAT | 0666);
    if (msgID >= 0) {
        printf("Warte auf Message Type %ldn", msgTyp);
        if (-1==msgrcv(msgID, &dataMsg, MSGSIZE, msgTyp, 0)) {
            perror("msgrcv"); /* Fehler */
        } else {
            /* Wir sind durchglaufen */
            printf("Daten empfangen: %sn", dataMsg.mtext);
        }
    } else {
        perror("msgget");
    }
}

Das Programm sndmsg.c sendet Nachrichten. Der Nachrichtentyp wird wie bei rcvmsg.c als erster Parameter übergeben. Als zweiter Parameter kann ein String übergeben werden, der dann als Daten in der Messages Queue abgestellt wird und den rcvmsg dann empfängt.

[Sende Nachrichten sndmsg.c]
#include <sys/ipc.h>
#include <sys/msg.h>

#define MSGSIZE 20

int main(int argc, char **argv)
{
int msgID;
struct myMsg {
  long mtype;
  char mtext[MSGSIZE];
} dataMsg;
long msgTyp = 0;

/* hole die Messagetypnummer aus dem ersten Parameter */
    if (argc>1) {
        dataMsg.mtype = atol(argv[1]);
    }
    if (argc>2) {
        strncpy(dataMsg.mtext, argv[2], MSGSIZE);
    } else {
        *dataMsg.mtext = 0;
    }
    /* Messagequeue oeffnen bzw. erzeugen */
    msgID = msgget(2404, IPC_CREAT | 0666);
    if (msgID >= 0) {
        printf("Sende Messagetyp %ldn", dataMsg.mtype);
        if (-1==msgsnd(msgID, &dataMsg, MSGSIZE, 0)) {
            perror("msgsnd"); /* Fehler */
        } else {
            /* Wir sind durchglaufen */
            printf("Daten gesendet: %sn", dataMsg.mtext);
        }
    } else {
        perror("msgget");
    }
}

Mit Hilfe der beiden Programme läßt sich das Verhalten der Message Queue leicht testen. Eine Anpassung an eigene Befürfnisse dürfte eine leichte Übung sein.

Die Message Queue bleibt solange erhalten, bis ein Programm sie explizit per msgctl() mit dem Kommando IPC_RMID entfernt, bis zum nächsten Shutdown oder bis sie mit dem Befehl ipcrm msg gelöscht wird (siehe S. ipcrm).



« Synchronisation mit Semaphoren | Prozesse | Leichtgewichtsprozesse: Threads »
 
 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