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 Funkion kill() kann ein Prozeß dem Anderen ein Signal schicken. Der Prozeß kann anschließend dementsprechend reagieren. Allerdings werden Signale äußerst selten als IPC's verwendet. Wollen wir uns doch mal bildlich ansehen wie das Funkitonieren könnte. Wie wollen mit fork einen 2.Prozeß kreiern. 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 Kindprozeß wird in einem Wartezustand versetzt und der Elternprozeß schreibt etwas auf dem Bildschirm.




Der Elternprozeß schickt dem Kindprozeß ein Signal mittels kill() und der Elternprozeß wird in einem Wartezustand versetzt.




Der Kindprozeß ist dran mit dem Schreiben auf dem Bildschirm.




Nun sendet der Kindprozeß dem Elternprozeß ein Signal mittels kill() und der Kindprozeß 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