ein Kapitel zurück                                           ein Kapitel weiter

Signale stellen die primitivste Art der Kommunikation zwischen 2 Prozessen da. Mit den Signalfunktionen alleine ist natürlich noch keine Interprozesskommunikation (IPC) möglich. Erst mit der Funktion kill() kann ein Prozess dem Anderen ein Signal schicken. Der Prozess kann anschließend dementsprechend reagieren. Allerdings werden Signale äußerst selten als IPC's verwendet. Wollen wir uns doch mal bildlich ansehen wie das Funktionieren könnte. Wie wollen mit fork einen 2.Prozeß kreieren. Beide Prozesse (Eltern und Kind) sollen anschließend abwechseln eine Ausgabe auf dem Bildschirm (STDOUT_FILENO) machen (anstatt dem Bildschirm können sie natürlich auch eine Datei verwenden). Folgendermaßen gehen wir dabei vor....




Der Kindprozess wird in einem Wartezustand versetzt und der Elternprozess schreibt etwas auf dem Bildschirm.




Der Elternprozess schickt dem Kindprozess ein Signal mittels kill() und der Elternprozess wird in einem Wartezustand versetzt.




Der Kindprozess ist dran mit dem Schreiben auf dem Bildschirm.




Nun sendet der Kindprozess dem Elternprozess ein Signal mittels kill() und der Kindprozess befindet sich wieder in einem Wartezustand.

Nun geht das ganze Spiel wieder von vorne los. Wollen wir uns nun das Programm dazu ansehen...............

/*Download:sigsync.c*/

#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
enum { FALSE, TRUE };

sigset_t sig_m1, sig_m2, sig_null;
int signal_flag=FALSE;

void sig_func(int signr)
{

 start_signalmenge();
 signal_flag = TRUE;
}


void start_signalmenge()
{

 if(signal(SIGUSR1, sig_func) == SIG_ERR)
  exit(0);
 if(signal(SIGUSR2, sig_func) == SIG_ERR)
  exit(0);

 sigemptyset(&sig_m1);
 sigemptyset(&sig_null);
 sigaddset(&sig_m1,SIGUSR1);
 sigaddset(&sig_m1,SIGUSR2);

 if(sigprocmask(SIG_BLOCK, &sig_m1, &sig_m2) <0)
   exit(0);
}

void message_for_parents(pid_t pid)
{

 kill(pid,SIGUSR2);
}

void wait_for_parents()
{

 while(signal_flag == FALSE)
  sigsuspend(&sig_null);
 signal_flag = FALSE;
 if(sigprocmask(SIG_SETMASK, &sig_m2, NULL)<0)
  exit(0);
}

void message_for_child(pid_t pid)
{

 kill(pid, SIGUSR1);
}

void wait_for_child(void)
{

 while(signal_flag == FALSE)
  sigsuspend(&sig_null);
 signal_flag = FALSE;
 if(sigprocmask(SIG_SETMASK, &sig_m2, NULL)<0)
   exit(0);
}


int main()
{

 pid_t pid;
 char x,y;
 start_signalmenge();

 switch( pid = fork())
  {

   case -1 : fprintf(stderr, "Fehler bei fork()\n");
             exit(0);
   case  0 : /*...im Kindprozess...*/
              for(x=2;x<=10;x+=2)
              {

               wait_for_parents();
               write(STDOUT_FILENO, "ping-",strlen("ping-"));
               message_for_parents(getppid());
              }

             exit(0);
   default : /*...im Elternprozess....*/
              for(y=1;y<=9;y+=2)
              {

               write(STDOUT_FILENO, "pong-", strlen("pong-"));
               message_for_child(pid);
               wait_for_child();
              }

   }
 printf("\n\n");
 return 0;
}

Ich habe in diesem Programmbeispiel auf Fehlerausgaben verzichtet. Sollten sie also wirklich vorhaben Signale zur Kommunikation zwischen 2 Prozessen zu verwenden so sollten sie dies als letzte Alternative verwenden. Denn sollten 2 Signale in zu kurzen Zeitabständen eintreffen, während der Signalhandler aktiv ist, kann es passieren das einige Signale dabei verloren gehen.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf