2015-12-18 2 views
0

Я участвую в разрешении упражнения с использованием вилки. Утверждение следующее: 1 родитель создает 3 ребенка, у них есть случайное и другое время выполнения, и они должны возвращать свои соответствующие значения родительскому. Таким образом, до сих пор я способен создавать и выполнять дочерние процессы и захватывать НЕКОТОРЫЕ из их значений, но после этого выполнение становится орехами. Код, который я получил до сих пор это:Асинхронное возвращение значений родительскому процессу

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

#define MAXCAPOS 3 
#define MAXCOMERCIOS 3 

/* Funcion que calcula aleatorios */ 
int calculaAleatorios(int min, int max) { 
    return rand() % (max-min+1) + min; 
} 

/* Funcion para dar más tiempo a que los negocios paguen */ 
void darPlazo() { 
    printf("\nDON: ¡Chicos! Decidle a los comerciantes que me deben dinero, que como no paguen lo que me deben, la semana que viene quemare sus tiendas."); 
} 

/* Funcion para dar una leccion a los negocios */ 
void darLeccion() { 
    printf("\nDON: ¡Chicos! Quemad los comercios que no han pagado esta semana."); 
} 

/* Funcion para generar un consejo */ 
void generaConsejo() { 
    sleep(10); 
    if(calculaAleatorios(0,1)==0) { 
     printf("\nConsigliere: Ya he deliberado SIGUSR1");  
     kill(getppid(), SIGUSR1); 
    } else { 
     printf("\nConsigliere: Ya he deliberado SIGUSR2"); 
     kill(getppid(), SIGUSR2); 
    } 
} 

int main(void){ 
    pid_t pidDon; 
    pid_t pidCapo[MAXCAPOS]; 
    pid_t pidConsigliere; 
    int i = 1, j = 1; 
    int totalImpagos = 0; 
    for (i; i <= MAXCAPOS; i++){ 
    /* Forkeando pidDon para obtener los capos */ 
    switch (pidDon = fork()){ 
     case -1: 
     perror("Error en la llamada a la funcion fork()"); 
     exit(EXIT_FAILURE); 
     break; 
     case 0: 
     { 
     int noPagan = 0, tiempo = 0; 
     pidCapo[i] = getpid(); 
     srand(pidCapo[i]); /*Generamos una semilla por el pid, dentro del proceso hijo para obtener semillas diferentes*/ 
     printf("\nDON: Contrato al capo%d (pid: %d)", i, pidCapo[i]); 
     /* VISITAR LOS COMERCIOS Y RECIBIR CUANTOS HAN PAGADO (int) */ 
     for (j; j <= MAXCOMERCIOS; j++){ 
      tiempo = calculaAleatorios(5, 10); /* Genera un tiempo aleatorio entre 5 y 10 */ 
      printf("\n Capo%d: %d Segundos para despertar (pid: %d)", i, tiempo, pidCapo[i]); 
      sleep(tiempo); 
      printf("\n Capo%d: Visita el comercio %d (pid: %d)", i, j, pidCapo[i]); 
      if (calculaAleatorios(0, 1) == 0){ 
      printf("\n Capo%d: El comercio %d no me ha pagado, malditas ratas!! (pid: %d)", i, j, pidCapo[i]); 
      noPagan++; 
      } else { 
      printf("\n Capo%d: El comercio %d ha pagado (pid:%d)", i, j, pidCapo[i]); 
      } 
     } 
     printf("\nCapo%d: tengo %d morosos", i, noPagan); 
     exit(noPagan); 
     break; 
     } 
     default: 
     break; 
    } 
    } 
    /*Proceso DON*/ 
    // Crear señales 
    printf("\nDON: Voy a esperar noticias de mis capos... (pid: %d)", getpid()); 
    signal(SIGUSR1, darPlazo); // Unimos la señal SIGUSR1 a su procedimiento 
    signal(SIGUSR2, darLeccion); //Unimos la señal SIGUSR2 a su procedimiento 
    if (pidDon != 0 && pidDon != -1){ 
    for (i = 1; i <= MAXCAPOS; i++){ 
     int retorno; 
     waitpid(pidCapo[i], &retorno, 0); 
     retorno = WEXITSTATUS(retorno); 
     printf("\nDON: Al capo %d no le han pagado %d comercios", i, retorno); 
     totalImpagos += retorno; 
    } 
    sleep(30); 
    if (totalImpagos == 0){ 
     printf("\nDON: Que bien, esta vez han pagado todos :D"); 
     printf("\nDON: He terminado mi dia\n"); 
     return (0); 
    } else { 
     if (totalImpagos == 1){ 
     printf("\nDON: No me ha pagado 1 comercio, grrrrrrrr!!!!"); 
     } 
     if (totalImpagos > 1){ 
     printf("\nDON: No me han pagado %d comercios, estoy muy encabronado!", totalImpagos); 
     } 
     printf("\nDON: Consultare con mi consigliere"); 
     /*Proceso Consigliere*/ 
     pidConsigliere = fork(); 
     if (pidConsigliere == -1){ 
     perror("\nFallo al crear el proceso Consigliere"); 
     exit(EXIT_FAILURE); 
     } 
     else if (pidConsigliere == 0){ 
     signal(SIGUSR1, generaConsejo); // Unimos la señal SIGUSR1 a su procedimiento 
     printf("\nConsigliere: Hola Don! Espero tu señal"); 
     pause(); 
     exit(0); 
     } 
     /*Vuelta al DON*/ 
     // Consulta al consigliere 
     sleep(5); 
     printf("\DON: Le mando una señal a mi consigliere"); 
     if (kill(pidConsigliere, SIGUSR1) == -1){ // Lanzamos kill contra pidConsigliere y evaluamos el error 
     perror("\nFallo al enviar la señal al Consigliere"); 
     exit(EXIT_FAILURE); 
     } 
     printf("\nDON: Esperare mientras mi consigliere delibera"); 
     pause(); 
    } 
    } 
    printf("\nDON: He terminado mi dia\n"); 
    return (0); 
} 

Итак, мне нужно знать, как правильно извлечь все 3 возвращаемые значения. Заранее спасибо.

+1

Вопросы, требующие помощи по отладке («почему этот код не работает?») Должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для воспроизведения в самом вопросе. Вопросы без четкого описания проблемы не полезны другим читателям. См.: Как создать минимальный, полный и проверенный пример. На английском пожалуйста! – Olaf

ответ

0

насчет установки обработчика сигнала для SIGCHLD в родительском и при вызове, пожинать статус выхода ребенка с wait(), waitpid() или wait4()?

Это каноническая практика. Я не совсем уверен, какой должна быть цель SIGUSR1/2.

0

Так, до сих пор я способен создавать и выполнять дочерние процессы и захватить некоторые из их значений, но исполнение becames гайки после этого.

Вы индексировать pidCapo[i] со значениями для i от 1 к MAXCAPOS, что неверно, поскольку массивы индексируются 0 на.

Смежные вопросы