Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger

 << zurück
Linux-UNIX-Programmierung von Jürgen Wolf
Das umfassende Handbuch – 2., aktualisierte und erweiterte Auflage 2006
Buch: Linux-UNIX-Programmierung

Linux-UNIX-Programmierung
1216 S., mit CD, 49,90 Euro
Rheinwerk Computing
ISBN 3-89842-749-8
gp Kapitel 8 Signale
  gp 8.1 Grundlage zu den Signalen
    gp 8.1.1 Signalmaske
    gp 8.1.2 Signale und fork()
    gp 8.1.3 Signale und exec
    gp 8.1.4 Übersicht zu den Signalen
  gp 8.2 Das neue Signalkonzept
    gp 8.2.1 Wozu ein »neues« Signalkonzept?
  gp 8.3 Signalmenge initialisieren
  gp 8.4 Signalmenge hinzufügen oder löschen
  gp 8.5 Signale einrichten oder erfragen
    gp 8.5.1 Einen Signalhandler einrichten, der zurückkehrt
  gp 8.6 Signal an den eigenen Prozess senden – raise()
  gp 8.7 Signale an andere Prozesse senden – kill()
  gp 8.8 Zeitschaltuhr einrichten – alarm()
  gp 8.9 Prozesse stoppen, bis ein Signal eintritt – pause()
  gp 8.10 Prozesse für eine bestimmte Zeit stoppen – sleep() und usleep()
  gp 8.11 Signalmaske erfragen oder ändern – sigprocmask()
  gp 8.12 Prozess während einer Änderung der Signalmaske stoppen – sigsuspend()
  gp 8.13 Prozesse synchronisieren


Rheinwerk Computing

8.13 Prozesse synchronisieren  toptop

Wollen Sie, dass zwei Prozesse abwechselnd ihre Arbeit verrichten, müssen Sie diese synchronisieren. Wenn Sie dies nicht tun und zwei Prozesse schreiben abhängig voneinander etwas in eine Datei, bekommen Sie einen Datensalat, denn nunmehr ist es abhängig vom Prozess-Scheduler, in welcher Reihenfolge und wie lange ein Prozess die CPU bekommt. Die Reihenfolge lässt sich, wenn auch in der Praxis nicht so üblich, mit Signalen lösen. Wie schon versprochen, soll hier demonstriert werden, wie Sie den Eltern- und Kindprozess mit Signalen synchronisieren können. Dazu werden gewöhnlich die Signale SIGUSR1 und SIGUSR2 mittels kill() an den entsprechenden Prozess gesendet. Ebenso finden Sie hier die Anwendung der Funktionen sigprocmask() und sigsuspend().

/* sig_sync.c */
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd. h.>
#include <errno.h>
#define MAX 5
typedef void (*sighandler_t)(int);
static volatile sig_atomic_t flag = 0;
static sigset_t mask_neu, mask_alt, mask_null;
static void sig_func(int);
static sighandler_t
my_signal (int sig_nr, sighandler_t signalhandler) {
   struct sigaction neu_sig, alt_sig;
   neu_sig.sa_handler = signalhandler;
   sigemptyset (&neu_sig.sa_mask);
   neu_sig.sa_flags = SA_RESTART;
   if (sigaction (sig_nr, &neu_sig, &alt_sig) < 0)
      return SIG_ERR;
   return alt_sig.sa_handler;
}
static void start_sync(void) {
   my_signal( SIGUSR1, sig_func );
   my_signal( SIGUSR2, sig_func );
   sigemptyset(&mask_null);
   sigemptyset(&mask_neu);
   sigaddset(&mask_neu, SIGUSR1 );
   sigaddset(&mask_neu, SIGUSR2 );
   if( sigprocmask(SIG_BLOCK, &mask_neu, &mask_alt) < 0 ) {
      printf("Fehler bei sigprocmask() ...\n");
      exit(EXIT_FAILURE);
   }
}
static void sig_func( int sig_nr ) {
   start_sync();
   flag = 1;
}
static void kind2eltern( pid_t pid ) {
   kill( pid, SIGUSR1 );
}
static void eltern2kind( pid_t pid ) {
   kill( pid, SIGUSR2 );
}
static void kind_wartet( void) {
   while( !flag )
      sigsuspend(&mask_null);
   flag = 0;
   if( sigprocmask(SIG_BLOCK, &mask_alt, NULL) < 0 ) {
      printf("Fehler bei sigprocmask() ...\n");
      exit(EXIT_FAILURE);
   }
}
static void eltern_warten(void ) {
   while( !flag )
      sigsuspend(&mask_null);
   flag = 0;
   if( sigprocmask(SIG_BLOCK, &mask_alt, NULL) < 0 ) {
      printf("Fehler bei sigprocmask() ...\n");
      exit(EXIT_FAILURE);
   }
}
int main (void) {
   pid_t pid;
   int j, i;
   
   start_sync();
   if( (pid=fork()) <0) {
      perror("fork()");
      return EXIT_FAILURE;
   }
   else if(pid == 0) {
      for(i = 0; i < MAX; i++) {
         kind_wartet();
         printf("Kind \n");
         kind2eltern(getppid());
       }
      printf("--- Kind Ende ---\n");
      exit(EXIT_SUCCESS);
   }
   for(j = 0; j < MAX; j++) {
      printf("Eltern \n");
      eltern2kind(pid);
      eltern_warten();
     }
   printf("--- Eltern Ende ---\n");
   return EXIT_SUCCESS;
}

Das Programm bei der Ausführung:

$ gcc -o sig_sync sig_sync.c
$ ./sig_sync
Eltern
Kind
Eltern
Kind
Eltern
Kind
Eltern
Kind
Eltern
Kind
--- Eltern Ende ---
--- Kind Ende ---

Zugegeben, zu den Signalen lässt sich noch eine Menge mehr schreiben. Aber irgendwo muss man Schluss machen. Sofern Sie des Englischen mächtig sind, empfehle ich Ihnen dazu die Dokumentation der GNU C Library, in der Sie eine Menge mehr Informationen und auch Code zu den Signalen und deren Behandlung finden. Eine weitere lebensnotwendige Lektüre wären die Manual Pages (man sigsetops, man sigaction, man sigsetjmp, man sigaltstack).

 << zurück
  
  Zum Rheinwerk-Shop
Neuauflage: Linux-UNIX-Programmierung
Neuauflage:
Linux-UNIX-
Programmierung

bestellen
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: Linux-Server






 Linux-Server


Zum Rheinwerk-Shop: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Rheinwerk-Shop: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Rheinwerk-Shop: Shell-Programmierung






 Shell-
 Programmierung


Zum Rheinwerk-Shop: Linux Handbuch






 Linux Handbuch


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
Info





Copyright © Rheinwerk Verlag GmbH 2006
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.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern