PDA

View Full Version : [C]Processi e Segnali


kwb
29-02-2012, 23:32
Ciao a tutti!
Ho da fare un programma in C su sistema *NIX dove il padre crea un figlio, il figlio invia un SIGUSR1 al padre. Il padre riceve il segnale, lo stampa e invia al figlio il segnale SIGUSR2. Il figlio riceve il segnale e lo stampa.

Ho usato una funzione handler per fare sta cosa, ma ho comunque problemi, perchè sebbene riesca a inviare il segnale al padre e farlo stampare, poi non riesco a inviare dal padre il segnale al figlio...
Ecco cosa ho scritto:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>

void signalRx(int segnale);

int main (int argc, const char * argv[])
{
int pid;

printf("Parent pid is: %d\n\n", getpid());
if((pid=fork())!=0) //Parent
{
signal(SIGUSR1, signalRx);
printf ("After signal in parent\n");
wait(0); //We must wait because the child might not have taken control
kill(pid, SIGUSR2);
wait(0);
printf("After kill in parent\n");
return 0;
}
else //Child
{
signal(SIGUSR2, signalRx);
printf("Child 1 ( %d ) of parent %d\n\n", getpid(), getppid());
kill(getppid(), SIGUSR1);
printf("After kill in child\n");
}
}

void signalRx(int segnale)
{
if(segnale==SIGUSR1)
printf("SIGUSR1 received by process %d\n", getpid());

if(segnale==SIGUSR2)
printf("SIGUSR2 received by process %d\n", getpid());
}

kwb
01-03-2012, 10:51
Sono mezzo riuscito a far funzionare il programma, con le cattive.
Ho dichiarato una variabile globale per tenere il pid del figlio. Appena entro nel figlio, uso getpid() per inizializzarela variabile con il pid del figlio.

Così facendo, quando entro nel primo if del mio handler, faccio una kill usando la variabile globale.
Mi stampa il segnale, intercettato dal giusto processo ( il figlio ) ma il programma rimane in stallo poi.
C'è da dire che ho dovuto mettere un pause() dentro il figlio, altrimenti non funzionava... Tuttavia anche usando un raise(SIGTERM) non riesco a terminare il figlio.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>

void signalRx(int segnale);
int pidch;
int main (int argc, const char * argv[])
{
int pid;

printf("Parent pid is: %d\n\n", getpid());
if((pid=fork())!=0) //Parent
{
signal(SIGUSR1, signalRx);
printf ("After signal in parent\n");
wait(0); //We must wait because the child might not have taken control
//kill(pid, SIGUSR2);
//wait(0);
printf("After kill in parent\n");
return 0;
}
else //Child
{
pidch=getpid();
signal(SIGUSR2, signalRx);
printf("Child 1 ( %d ) of parent %d\n\n", getpid(), getppid());
kill(getppid(), SIGUSR1);
printf("After kill in child\n");
pause();
exit(0);
}

}

void signalRx(int segnale)
{
if(segnale==SIGUSR1)
{
printf("SIGUSR1 received by process %d\n", getpid());
kill(pidch, SIGUSR2);
}

if(segnale==SIGUSR2)
{
printf("SIGUSR2 received by process %d\n", getpid());
signal(SIGTERM, SIG_DFL);
raise(SIGTERM);
}
}


Idee?

Chiaramente se qualcuno ha una soluzione migliore che non richieda la dichiarazione di una variabile globale, ben venga!