ayuda con hijos y padres

Imagen de takyo
0 puntos

buenas, hacer esperar un padre a sus hijos o a un hijo que muera en concreto es muy facil con wait/waitpid, pero hacer esperar a todos sus hijos o a uno en concreto hasta que les mande una "colleja" el padre no se muy bien como se hace

alguien me ayudaria?

gracias!!!

Imagen de slap
+1
0
-1

Si, por lo que entiendo, lo que quieres es que un hijo espere a que el padre le mande una señal, el hijo debería ejecutar un pause().

Saludos.
slap

+1
0
-1

Saludos.

0000 start out (+FD),A
           ld  BC, +7FFF
           jp 03CB, RAM-CHECK

http://www.injiniero.es

Imagen de takyo
+1
0
-1

ok, ahora mi duda se tuerce y se complica bastante al ser varios hijos, en fin vamos al grano

he conseguido que me fabrique tantos hijos como quiera, he conseguido que el padre se espere a que todos terminen, creo que he conseguido liberar a todos los hijos, pero el problema es que solo los libera cuando estos ya estan parados

aqui presento el codigo


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

typedef struct

{

pid_t pid;  //pid del hijo

int num,   //numero de orden del hijo
    tubo[2], // tubo
    estado;  // estado del hijo

long premio; //premio del hijo en un sorteo

} T_HIJO ;

int toke=1;
int parada=0;
/******************************/
void kolleja(int sig)
{
parada++;
signal(SIGUSR1, kolleja);
printf("kolleja padre %d\n",parada);// parada siempre vale 1, el porque no lo se

}
/************************************/
void kapon (int sig)
{
printf("\n\nkapon nº %d\n\n",toke);
toke++;
//signal(SIGCHLD,kapon);
signal(SIGUSR2,kapon);
}

/**********************************/
/**********************************/
int main(int argc, char *argv[])

{

    int    kiki = 0, jug = atoi(argv[1]);
    T_HIJO jugador[jug];

    signal(SIGUSR1, kolleja);
    //signal(SIGCHLD,kapon);
    signal(SIGUSR2,kapon);
printf("******************CREANDO HIJOS******************\n\n");

    do{

        kiki++;

        jugador[kiki].pid = fork();

        if( jugador[kiki].pid < 0 )

        {

            perror(argv[0]);

            return 1;

        }
   

    }while( jugador[kiki].pid != 0 && kiki < jug);

    if( jugador[kiki].pid == 0 )

    {

        // El hijo

        printf("[Hijo] %d my pid:%ld mi padre es %ld\n [hijo] el %d en espera del padre", kiki, (long)getpid(), (long)getppid(),kiki);

        fflush(stdout);

//        pause();// SI SE OMITE PAUSE HARÁ CASO AL KILL CASI SIEMPRE, EN OTRO CASO PASARA COMO SI NO VIERA NADA
        printf("[hijo] %d liberado!!!\n",kiki);
        kill(getppid(),SIGUSR2);// IGNORADO INEXPLICABLEMENTE SI SE ACTIVA EL PAUSE

        printf("[hijo] el %d terminó pid %ld toke [%d]\n", kiki, (long)getpid(),toke);

        exit(6);

    }

    else if( jugador[kiki].pid > 0 )

    {

        // El padre
printf("\n\n*******PADRE DE LOS HIJOS********\n");

    printf("[Padre] my pid: %ld\n", (long)getpid(),toke);

    fflush(stdout);

printf("\n\n*******PADRE EMPIEZA LIBERAR TODOS LOS HIJOS********\n");   
    for(kiki=0;kiki<jug;kiki++)    // libero a todos los hijos
        kill(jugador[kiki].pid,SIGUSR1);

printf("\n\n**** PADRE ESPERA A QUE TERMINEN TODOS LOS HIJOS ****\n");

    for (kiki=0; kiki<jug ; kiki++ )// SE ESPERA A QUE TERMINEN TODOS LOS HIJOS
        waitpid(jugador[kiki].pid,&jugador[kiki].estado,0);

        printf("[padre]Despues de wait, numero de procesos creados %d\n", kiki);

        fflush(stdout);
    }
exit(0);
}

alguien podria ayudarme?
lo que busco es que los hijos se paren hasta que el padre les mande una señal y que el padre se pare hasta que TODOS los hijos les manden una señal, que actuen parecidos a los semaforos
gracias por prestarme atencion!!!

un saludo

+1
0
-1
Imagen de slap
+1
0
-1

Hola.
No acabo de entender cual debe ser el mecanismo de envío de señales y esperas.

Dices que quieres que los hijos se paren hasta que el padre les mande una señal y que el padre se pare hasta que todos los hijos le manden una señal.

El comportamiento del hijo:

- Espero a que mi padre me envíe una señal.
- Cuando la reciba, envío una señal a mi padre y muero.

El comportamiento del padre:

- Envío una señal a cada hijo.
- Espero a recibir una señal de algún hijo.
- Si quedan hijos vuelvo al paso anterior.

¿es esto lo que quieres?

Si es así, el procedimeinto sería:

El hijo:
- pause()
- El manejador de la señal que esperas debería activar un flag para saber si se ha recibido la señal esperada. En caso contrario, el flag debe quedar inactivo.
- Comprobar flag.
- Si flag activo:
- Enviar señal al padre.
- Morir.
- Si flag no activo:
- Volver al pause().

El padre:
- Envío una señal a cada hijo.
- pause()
- El manejador de la señal debería contar el número de veces que la recibe.
- Si contador < número hijos:
- Volver al pause()
- Si no:
- fin.

Más o menos esto es lo que debería ocurrir. Probablemente haya que ajustar cosas. Son ideas generales. No he probado nada de esto.

Respecto al código que envías, hay muchos errores:

  • Te falta incluir <signal.h>
  • No es necesario que redefinas el manejador de la señal dentro del propio manejador
  • Después de crear los hijos, el código:
      if( jugador[kiki].pid == 0 )
    

    hace referencia al último hijo sólo. Igual pasa en el else

¿Tienes claro cómo se ejecuta el padre y cómo los hijos cuando haces un fork()?

Saludos.
slap

+1
0
-1

Saludos.

0000 start out (+FD),A
           ld  BC, +7FFF
           jp 03CB, RAM-CHECK

http://www.injiniero.es

Imagen de slap
+1
0
-1

Te dejo un ejemplo de cómo debería funcionar:

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

int quedanhijos = 0;
int estado;

void hsigusr1 (int sig){ // Manejador para los hijos
  printf("Hijo: %d recibe señal: %d\n",getpid(),sig);
  fflush(stdout);
}

void hsigusr2 (int sig){ // Manejador para el padre
  quedanhijos--;
  printf("Padre recibe señal: %d de un hijo.\n",sig);
  printf("Quedan: %d hijos.\n",quedanhijos);
  fflush(stdout);
}

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

  int i = -1;
  int hijos = 0;
  int phijos[10];
  int pid = 0;


  if (argc != 2){
    printf("Uso: %s <numhijos>.\n",argv[0]);
    exit(0);
  }

  hijos = atoi(argv[1]);
  if (hijos<1 || hijos>10){
    printf("Forzando a 1 hijo.\n");
    hijos = 1;
  }

  quedanhijos = hijos;
  printf("Creando: %d hijos.\n",hijos);
  do {
    i++;
    pid = phijos[i] = fork();

    if (phijos[i] < 0) {
      perror(strerror(errno));
      exit(-1);
    }
  }while(pid>0 && i<hijos-1);

  // Aquí pid = 0 para los hijos y > 0 para el padre

  if (pid == 0) { // Hijos
    signal(SIGUSR1,hsigusr1);
    printf("Hijo: %d esperando.\n",getpid());
    fflush(stdout);
    pause(); // Queda a la espera de la señal del padre
    printf("Hijo: %d liberado.\n",getpid());
    fflush(stdout);
    kill(getppid(),SIGUSR2); // Avisa al padre
    exit(1); // y muere
  } else { // Padre
    signal(SIGUSR2,hsigusr2);
    for (i=0;i<hijos;i++){ // Libero a los hijos
      kill(phijos[i],SIGUSR1);
      sleep(1); // Hay que darles tiempo
    }
    while(quedanhijos){ // Espero a los hijos
      pause();
      wait(&estado); // Libero recursos del hijo
    }
  }
  exit(0);
}

Saludos.
slap

+1
0
-1

Saludos.

0000 start out (+FD),A
           ld  BC, +7FFF
           jp 03CB, RAM-CHECK

http://www.injiniero.es

Imagen de yaiza
+1
0
-1

Es un ejemplo perfecto para la creación de hijos con un padre. Sin embargo, estoy haciendo un programa que además de crear un padre con varios hijos y se pasen señales necesitaría que se enviaran mensajes a trávés de los pipes. Estoy atrancada intentando utilizar tu ejemplo para que el padre y los hijos se envíen mensajes pero no salgo... Me sería de gran ayuda un ejemplo de la calidad de este. Muchísimas gracias por anticipado.
Saludos, Yaiza

+1
0
-1
Imagen de takyo
+1
0
-1

muchas gracias por la ayuda y la solucion

me has echo un mundo, ahora si que comprendo las señales a la perfeccion

en fin, un beso virtual para ti

MUAK!!!

+1
0
-1