Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Concurrencia

Estas en el tema de Concurrencia en el foro de C/C++ en Foros del Web. Hola, he creado tres procesos hijos utilizando fork. Guardo los pid de los procesos hijos en un array llamado p. Los procesos hijos deben ejecutar ...
  #1 (permalink)  
Antiguo 18/04/2016, 11:37
 
Fecha de Ingreso: abril-2016
Mensajes: 5
Antigüedad: 3 años, 7 meses
Puntos: 0
Concurrencia

Hola, he creado tres procesos hijos utilizando fork. Guardo los pid de los procesos hijos en un array llamado p. Los procesos hijos deben ejecutar la misma función de forma infinita. Solo consigo que el primer hijo ejecute la función de forma infinita. ¿Cómo podría hacer que los demás hijos también la ejecutasen? Gracias de antemano.

Código:
if(padre)
{
   for(i=0; i<HIJOS; i++)
   {
      if(p[i])
      {
         for(;;)
         {
            funcion();
         }
      }
   }
}
  #2 (permalink)  
Antiguo 18/04/2016, 11:48
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 5 años, 2 meses
Puntos: 204
Respuesta: Concurrencia

yo ahí no veo ningún fork y dado que no soy mago ni vidente no puedo adivinar el diseño de tu algoritmo... ¿tanto cuesta poner ejemplos completos?
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #3 (permalink)  
Antiguo 18/04/2016, 11:57
 
Fecha de Ingreso: abril-2016
Mensajes: 5
Antigüedad: 3 años, 7 meses
Puntos: 0
Respuesta: Concurrencia

Este es el código con fork:

Código:
for(i=0; i<HIJOS && padre; i++)
{
   if((padre = fork()) == -1)
   {
      exit(EXIT_FAILURE);
   }
   else
   {
      p[i] = padre;
   }
}

if(padre)
{ 
   for(i=0; i<HIJOS; i++)
   {
       if(p[i])
       {
          for(;;)
          {
              funcion();
          }
       }
   }
}
else
{
}
  #4 (permalink)  
Antiguo 18/04/2016, 12:15
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 5 años, 2 meses
Puntos: 204
Respuesta: Concurrencia

Código C:
Ver original
  1. for(i=0;i<2;i++)
  2.   fork();

Pregunta: ¿Cuántos hilos habrá al terminar ese bucle?

Respuesta: 4

Explicación:
  • En la primera iteración tendremos dos, el padre (P) y un hijo (H1)
  • En la segunda iteración tendremos 4 ( P crea 1 y H1 crea otro)
Luego tu intento de crear únicamente N hijos no funciona porque estás creando un número de hijos desproporcionado.

Por otro lado, llamar a fork hace que el hijo tenga una copia de la memoria del padre y a partir de ese momento cada uno usa su propia memoria... almacenar en un arreglo los id no parece una buena idea porque cada proceso va a almacenar un arreglo diferente.

Si el número de hijos es una constante puedes probar algo tal que:

Código C:
Ver original
  1. if( fork() )
  2.   if( fork() )
  3.     if( fork() )
  4.       return; // Aqui solo llega el padre
  5.  
  6. funcion(); // Los 3 hijos ejecutan esto

También puedes embeber el código en un bucle... pero teniendo cuidado de crear procesos únicamente desde el padre:

Código C:
Ver original
  1. #define HIJOS 3
  2. int main()
  3. {
  4.   int padre = getpid();
  5.  
  6.   for( int i=0;i<HIJOS;i++)
  7.     if( !fork() ) break;
  8.  
  9.   if( getppid() == padre ) // Si el padre del proceso actual es el proceso principal estamos tratando con un hijo
  10.     printf("1");
  11. }

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.

Última edición por eferion; 18/04/2016 a las 12:25
  #5 (permalink)  
Antiguo 18/04/2016, 12:49
 
Fecha de Ingreso: abril-2016
Mensajes: 5
Antigüedad: 3 años, 7 meses
Puntos: 0
Respuesta: Concurrencia

Ahora se crean bien los procesos hijos. El problema es que al ejecutar la función de forma infinita, el primer proceso entra en el bucle infinito y los demás procesos mueren. Así lo tengo ahora:

Código:
padre = getpid();
for(i=0; i<HIJOS; i++)
{
   if(!fork())
   {
      break;
   }
}
if(getppid() == padre) // Hijos.
{
   for(;;)
   {
      funcion();
   }
}
  #6 (permalink)  
Antiguo 18/04/2016, 12:57
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 5 años, 2 meses
Puntos: 204
Respuesta: Concurrencia

Si yo ejecuto esto:

Código C:
Ver original
  1. #define HIJOS 3
  2.  
  3. int main()
  4. {
  5.   int padre = getpid();
  6.   printf("%d <- principal\n", padre);
  7.  
  8.   for(int i=0; i<HIJOS; i++)
  9.   {
  10.     if(!fork())
  11.     {
  12.       break;
  13.     }
  14.   }
  15.   if(getppid() == padre) // Hijos.
  16.   {
  17.     printf("%d <- hijo\n",getpid());
  18.   }
  19. }

Obtengo esto:

Código BASH:
Ver original
  1. 29387 <- principal
  2. 29389 <- hijo
  3. 29387 <- principal
  4. 29387 <- principal
  5. 29390 <- hijo
  6. 29387 <- principal
  7. 29391 <- hijo

Es decir, en el if únicamente entran los procesos hijos.

Salvo que estés creando otros procesos antes de llegar aquí no se me ocurre cómo te puede estar fallando.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #7 (permalink)  
Antiguo 18/04/2016, 13:00
 
Fecha de Ingreso: abril-2016
Mensajes: 5
Antigüedad: 3 años, 7 meses
Puntos: 0
Respuesta: Concurrencia

Sí, el problema es cuando ejecuto la función con el bucle infinito. Es que esa función deben ejecutarla todos los procesos a la vez de forma infinita, pero solo me deja que la ejecute el primero.
  #8 (permalink)  
Antiguo 18/04/2016, 13:10
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 5 años, 2 meses
Puntos: 204
Respuesta: Concurrencia

¿Es esto acaso una práctica de clase o tu proyecto tiene una utilidad real?

Si es lo segundo posiblemente sea mejor pasar de fork y usar hilos.

En cualquier caso has de tener en cuenta las limitaciones del SO que uses. También has de tener en cuenta que no es lo mismo que el hilo o proceso se ejecute a nivel de SO que a nivel de aplicación. En el segundo caso un hilo que entre en un bucle sin fin puede dejar bloqueados a todos los demás.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #9 (permalink)  
Antiguo 18/04/2016, 13:21
 
Fecha de Ingreso: abril-2016
Mensajes: 5
Antigüedad: 3 años, 7 meses
Puntos: 0
Respuesta: Concurrencia

Es para una práctica de clase. ¿Habría otra forma de que se ejecutase todo el rato una función sin utilizar un bucle infinito? Para que no se bloqueasen los demás procesos.
  #10 (permalink)  
Antiguo 18/04/2016, 17:00
 
Fecha de Ingreso: febrero-2015
Mensajes: 400
Antigüedad: 4 años, 9 meses
Puntos: 3
Respuesta: Concurrencia

Cita:
Iniciado por katerinadobreva Ver Mensaje
Es para una práctica de clase. ¿Habría otra forma de que se ejecutase todo el rato una función sin utilizar un bucle infinito? Para que no se bloqueasen los demás procesos.
Una forma que suelo usar aunque supongo que no será lo más correcto es poner dentro de ese bucle un Sleep (100) por ejemplo. Eso hace que se pause el bucle 100 milisegundos y consigues que no se bloquee.
También depende mucho de lo que haga la función que esta dentro del bucle ya que si lo que esperas en el bucle es algún mensaje o evento quizás podrías usar hilos y esperar la respuesta lo que dejaría al hilo que espera la respuesta congelado a la espera de dicha respuesta. Con eso tampoco dejarías congelado el proceso. También podrías usar una función callback y desde la función que se ejecuta en tu caso envías un mensaje al proceso y lo gestionas sin más. Pipes, memoria compartida sockets y no se que más.

Etiquetas: concurrencia, funcion
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 08:22.