2012-09-07 3 views
6

Le mie domande sono:Perché i miei processi non vengono eseguiti contemporaneamente?

1.) Come posso ottenere che il processo genitore muoia sempre per ultimo? Capisco che questo non viene realizzato perché il genitore è il primo pid che viene eseguito, ma non so come cambiarlo.

2.) In che modo è possibile eseguire i processi di mio figlio nello stesso momento come il suo? Ho persino superato il numero molto alto per vedere se fosse solo una coincidenza, ma sembra non esserlo.

EDIT: SOLUZIONI

1.) aggiunto di attesa (NULL) due volte in default interno
2.) che stava accadendo. usato dormire (1) per dimostrarlo.

Il mio codice è il seguente

#include <stdio.h> 
int main() { 
    int pid, i; 
    pid = fork(); 
    switch(pid) { 
     case -1: 
      // error 
      printf("Fork error"); 
      break; 
     case 0: 
      // child process 
      printf("First child is born, my pid is %d\n", getpid()); 
      for(i=1; i<10; i++) 
       printf("First child executes iteration %d\n", i); 
      printf("First child dies quietly.\n"); 
      break; 
     default: 
      // parent process 
      printf("Parent process is born, my pid is %d\n", getpid()); 
      pid = fork(); 
      switch(pid) { 
       case -1: 
        // error 
        printf("Fork error"); 
        break; 
       case 0: 
        // child process 
        printf("Second child is born, my pid is %d\n", getpid()); 
        for(i=1; i<10; i++) 
         printf("Second child executes iteration %d\n", i); 
        printf("Second child dies quietly.\n"); 
        break; 
       default: 
        // parent process 
        printf("Parent process dies quietly."); 
     } 
    } 
    return 0; 
} 

mio output è sempre così:

 
Parent process is born, my pid is 7847 
First child is born, my pid is 7848 
First child executes iteration: 1 
First child executes iteration: 2 
First child executes iteration: 3 
First child executes iteration: 4 
First child executes iteration: 5 
First child executes iteration: 6 
First child executes iteration: 7 
First child executes iteration: 8 
First child executes iteration: 9 
First child executes iteration: 10 
First child dies quietly. 
Parent process dies quietly. 
Second child is born, my pid is 7849 
Second child executes iteration 1 
Second child executes iteration 2 
Second child executes iteration 3 
Second child executes iteration 4 
Second child executes iteration 5 
Second child executes iteration 6 
Second child executes iteration 7 
Second child executes iteration 8 
Second child executes iteration 9 
Second child executes iteration 10 
Second child dies quietly. 

Il mio compito è:

Scrivi un programma C ("procs.c"), che crea tre processi: un processo genitore che crea due processi figli.

Il primo bambino dovrebbe effettuare le seguenti operazioni:

  • visualizzazione "Il primo bambino è nato, il mio PID è ..."

  • visualizzazione dieci volte il messaggio "Il primo bambino esegue l'iterazione X" , dove X è il numero dell'iterazione

  • visualizzazione "Primo figlio muore in silenzio".

Il secondo bambino dovrebbe effettuare le seguenti operazioni:

  • visualizzazione "Il secondo bambino è nato, il mio PID è ..."

  • visualizzazione dieci volte il messaggio "esegue secondo figlio iterazione X ", dove X è il numero dell'iterazione

  • visualizzazione" Secondo figlio muore in silenzio ".

Il processo genitore dovrebbe fare il seguente:

  • visualizzazione "processo genitore è nato, il mio PID è ..."

  • creare il primo figlio

  • creare il secondo figlio

  • visualizzare "Parent processo muore silenziosamente."

compilare il programma usando gcc e il nome del file eseguibile 'procs' Eseguire il programma più volte e notare come l'uscita dei due figli interlacciata

Una possibile uscita di questo programma è:..

 
nova> ./procs 

Parent process is born, my pid is 7847 
First child is born, my pid is 7848 
First child executes iteration: 1 
First child executes iteration: 2 
First child executes iteration: 3 
First child executes iteration: 4 
First child executes iteration: 5 
Second child is born, my pid is 7849 
Second child executes iteration 1 
Second child executes iteration 2 
Second child executes iteration 3 
First child executes iteration: 6 
Second child executes iteration 4 
Second child executes iteration 5 
Second child executes iteration 6 
First child executes iteration: 7 
Second child executes iteration 7 
Second child executes iteration 8 
Second child executes iteration 9 
Second child executes iteration 10 
Second child dies quietly. 
First child executes iteration: 8 
First child executes iteration: 9 
First child executes iteration: 10 
First child dies quietly. 
Parent process dies quietly. 

risposta

3
  1. Il processo padre appropriata deve attendere (utilizzando wait() or waitpid() o una variante specifica della piattaforma) per i suoi figli a morire prima di uscire.

  2. L'esecuzione simultanea richiede che lo scheduler abbia la possibilità di essere eseguito. È possibile forzare il problema con le operazioni di sospensione (micro-sleep, nano-sleep) appropriate. Alcune chiamate di sistema saranno d'aiuto (quindi fflush(0) potrebbe essere d'aiuto).


#include <stdio.h> 
#include <sys/wait.h> 
#include <time.h> 
#include <unistd.h> 

int main(void) 
{ 
    int pid, i; 
    struct timespec tw = { .tv_sec = 0, .tv_nsec = 10000000 }; 
    pid = fork(); 
    switch(pid) 
    { 
     case -1: 
      printf("Fork error"); 
      break; 
     case 0: 
      printf("First child is born, my pid is %d\n", getpid()); 
      for(i=1; i<10; i++) 
      { 
       printf("First child executes iteration %d\n", i); 
       nanosleep(&tw, 0); 
      } 
      printf("First child dies quietly.\n"); 
      break; 
     default: 
      printf("Parent process is born, my pid is %d\n", getpid()); 
      pid = fork(); 
      switch(pid) 
      { 
       case -1: 
        printf("Fork error"); 
        break; 
       case 0: 
        printf("Second child is born, my pid is %d\n", getpid()); 
        for(i=1; i<10; i++) 
        { 
         printf("Second child executes iteration %d\n", i); 
         nanosleep(&tw, 0); 
        } 
        printf("Second child dies quietly.\n"); 
        break; 
       default: 
        printf("Parent process waiting for children.\n"); 
        int corpse; 
        int status; 
        while ((corpse = waitpid(0, &status, 0)) > 0) 
         printf("Child %d died with exit status 0x%.4X\n", corpse, status); 
        printf("Parent process dies quietly.\n"); 
        break; 
      } 
    } 
    return 0; 
} 

uscita Esempio:

Parent process is born, my pid is 46624 
First child is born, my pid is 46625 
First child executes iteration 1 
Parent process waiting for children. 
Second child is born, my pid is 46626 
Second child executes iteration 1 
First child executes iteration 2 
Second child executes iteration 2 
First child executes iteration 3 
Second child executes iteration 3 
First child executes iteration 4 
Second child executes iteration 4 
Second child executes iteration 5 
First child executes iteration 5 
Second child executes iteration 6 
First child executes iteration 6 
Second child executes iteration 7 
First child executes iteration 7 
Second child executes iteration 8 
First child executes iteration 8 
Second child executes iteration 9 
First child executes iteration 9 
First child dies quietly. 
Second child dies quietly. 
Child 46625 died with exit status 0x0000 
Child 46626 died with exit status 0x0000 
Parent process dies quietly. 

noti che i ritardi 10 millisecondi quasi costringono esecuzione alternata. Senza qualcosa di simile, sei bloccato con le idiosincrasie del tuo sistema e del suo programmatore, e molte macchine moderne sono semplicemente troppo veloci!

+0

Il mio libro ha un esempio proprio come il mio, eccetto il default ha anche un ciclo for. E i risultati spesso assomigliano a parent1, parent2, child1, child2, child3, child4, parent3, ecc. Nel mio, perché il secondo figlio non inizia a eseguire nel mezzo dell'esecuzione del 1 ° figlio? –

+1

La tua macchina è troppo veloce. –

+0

Grazie. Il tuo aiuto mi ha ispirato a gettare un sonno (1) nel processo del mio bambino per dimostrare che stavano correndo allo stesso tempo. –

1

fork() crea un nuovo processo figlio, che corsa di indipendentemente dal genitore.

Se si desidera che il processo padre di aspettare i bambini per finire, è possibile utilizzare la chiamata di sistema wait, passando un PID, che bloccherà fino al termine del processo.

vedere l'articolo wait(System Call) on Wikipedia