Aintzane
2004-07-02 08:01:33 UTC
Hola a todos, tengo un problema al trabajar con señales. He hecho un
programa de prueba muy sencillo, pero no funciona. Este programa hace
lo siguiente: hay un proceso padre que está ejecutándose
continuamente, y lanzando procesos hijos (como máximo 10 a la vez). El
proceso padre no hace nada, los hijos esperan un segundo y mueren. He
creado una rutina (Rutina 1) que se ejecuta cada vez que un hijo muere
(señal SIGCLD), esta rutina lo único que hace es escribir en un
fichero (prueba.txt) que se ha ejecutado y decrementar el número de
hijos que hay lanzados en ese momento.
El problema es que al ejecutar el programa se queda colgado, y no
encuentro el problema. ¿Hay algún problema en que la rutina aosicada a
una señal bloquee esa misma señal? Este es el código que he escrito:
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
sigset_t signalSIGCLD;
struct sigaction sa;
int hijo;
int contador=0;
void Rutina1 (void);
void Escribe(char * texto)
{
int hFile;
if(NULL==texto)
return;
hFile=open("prueba.txt",O_CREAT|O_APPEND|O_WRONLY,0755);
write(hFile,texto,strlen(texto));
close(hFile);
}
void main (void)
{
int pid;
int nums=30;
char texto[1000];
hijo = 1;
if(0==fork()){
sigemptyset (&signalSIGCLD);
sigaddset(&signalSIGCLD, SIGCLD);
sigemptyset (&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGCLD);
sa.sa_flags = SA_RESTART;
sa.sa_handler = Rutina1;
sigaction (SIGCLD, &sa, NULL);
signal(SIGCLD,Rutina1);
while (1)
{ if(hijo<=10){
if ((pid=fork()) == -1)
{
printf("Error al generar el proceso hijo\n");
exit(0);
}
else if (pid == 0)
{
/*Proceso Hijo*/
sleep(1);
exit(0);
}
else
{
/*Proceso Padre*/
}
hijo++;
}
}
}
}
void Rutina1 (void)
{
int rc, i;
char texto[1000];
signal(SIGCLD,Rutina1);
sigprocmask(SIG_BLOCK, &signalSIGCLD, NULL);
while (-1==(rc=wait(&i)));
sprintf(texto,"Inicio Rutina 1, %d, proceso: %d\n", contador+1,rc);
Escribe(texto);
contador++;
sprintf(texto, "Fin Rutina 1, %d, proceso: %d\n", contador, rc);
Escribe(texto);
hijo--;
sigaction (SIGCLD, &sa, NULL);
signal(SIGCLD, Rutina1);
sigprocmask(SIG_UNBLOCK, &signalSIGCLD, NULL);
}
Muchas gracias,
Aintzane
programa de prueba muy sencillo, pero no funciona. Este programa hace
lo siguiente: hay un proceso padre que está ejecutándose
continuamente, y lanzando procesos hijos (como máximo 10 a la vez). El
proceso padre no hace nada, los hijos esperan un segundo y mueren. He
creado una rutina (Rutina 1) que se ejecuta cada vez que un hijo muere
(señal SIGCLD), esta rutina lo único que hace es escribir en un
fichero (prueba.txt) que se ha ejecutado y decrementar el número de
hijos que hay lanzados en ese momento.
El problema es que al ejecutar el programa se queda colgado, y no
encuentro el problema. ¿Hay algún problema en que la rutina aosicada a
una señal bloquee esa misma señal? Este es el código que he escrito:
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
sigset_t signalSIGCLD;
struct sigaction sa;
int hijo;
int contador=0;
void Rutina1 (void);
void Escribe(char * texto)
{
int hFile;
if(NULL==texto)
return;
hFile=open("prueba.txt",O_CREAT|O_APPEND|O_WRONLY,0755);
write(hFile,texto,strlen(texto));
close(hFile);
}
void main (void)
{
int pid;
int nums=30;
char texto[1000];
hijo = 1;
if(0==fork()){
sigemptyset (&signalSIGCLD);
sigaddset(&signalSIGCLD, SIGCLD);
sigemptyset (&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGCLD);
sa.sa_flags = SA_RESTART;
sa.sa_handler = Rutina1;
sigaction (SIGCLD, &sa, NULL);
signal(SIGCLD,Rutina1);
while (1)
{ if(hijo<=10){
if ((pid=fork()) == -1)
{
printf("Error al generar el proceso hijo\n");
exit(0);
}
else if (pid == 0)
{
/*Proceso Hijo*/
sleep(1);
exit(0);
}
else
{
/*Proceso Padre*/
}
hijo++;
}
}
}
}
void Rutina1 (void)
{
int rc, i;
char texto[1000];
signal(SIGCLD,Rutina1);
sigprocmask(SIG_BLOCK, &signalSIGCLD, NULL);
while (-1==(rc=wait(&i)));
sprintf(texto,"Inicio Rutina 1, %d, proceso: %d\n", contador+1,rc);
Escribe(texto);
contador++;
sprintf(texto, "Fin Rutina 1, %d, proceso: %d\n", contador, rc);
Escribe(texto);
hijo--;
sigaction (SIGCLD, &sa, NULL);
signal(SIGCLD, Rutina1);
sigprocmask(SIG_UNBLOCK, &signalSIGCLD, NULL);
}
Muchas gracias,
Aintzane