|
![ein Kapitel weiter](../weiter.gif)
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 weiter](../weiter.gif)
© 2001,2002 Jürgen Wolf
|