2015-07-03 15 views
7

Ho un codice semplice per testare la funzione fork().Il processo figlio inizia dopo il processo principale

#include<stdio.h> 
    #include<unistd.h> 
    #define MAX_COUNT 10 
    void main(void) 
    { 
     pid_t pid; 
     int i; 
     fork(); 
     pid = getpid(); 
     for(i = 1; i <= MAX_COUNT; i++) 
     { 
      printf("PID = %d, i = %d\n", pid, i); 
     } 
    } 

Non ha funzionato come mi aspettavo.

La mia aspettativa è: il risultato del genitore e il risultato del bambino appaiono alternativamente. Qualcuno può spiegarlo e insegnarmi come risolverlo? Grazie!

PID = 3663, i = 1 
    PID = 3663, i = 2 
    PID = 3663, i = 3 
    PID = 3663, i = 4 
    PID = 3663, i = 5 
    PID = 3663, i = 6 
    PID = 3663, i = 7 
    PID = 3663, i = 8 
    PID = 3663, i = 9 
    PID = 3663, i = 10 
    PID = 3664, i = 1 
    PID = 3664, i = 2 
    PID = 3664, i = 3 
    PID = 3664, i = 4 
    PID = 3664, i = 5 
    PID = 3664, i = 6 
    PID = 3664, i = 7 
    PID = 3664, i = 8 
    PID = 3664, i = 9 
    PID = 3664, i = 10 
+7

I due processi operano in modo indipendente, quindi non è possibile aspettarsi alcun ordine specifico una volta che la forcella si è verificata (dipende dalla pianificazione del sistema operativo). Se si desidera un ordine specifico, è necessario farlo esplicitamente da soli con i meccanismi di sincronizzazione. Ad esempio, attendere, semafori, mutex, pipe, ecc. – kaylum

+0

Intendevo ordinamento tra i processi, ovviamente. Ordinare all'interno del processo è ben definito in modo naturale. – kaylum

+0

prova ad aggiungere "sleep (1);" al tuo ciclo for. – QuestionC

risposta

9

La spiegazione è semplice. La pianificazione dei processi dipende dal kernel. Se si tratta di un processore single core, in questa esecuzione ha deciso di sospendere l'esecuzione del figlio e consentire l'esecuzione del processo genitore. Il genitore ha eseguito alcuni loop prima di essere sospeso a favore del bambino, e così via.
In un sistema multiprocessore, entrambi i processi possono essere eseguiti in tandem ma il dispositivo console alternerà l'uscita in base al tempo di interruzione.

Non vi è alcuna garanzia che un'esecuzione diversa comporterà la stessa uscita. Inoltre, non vi è alcuna garanzia che la versione del kernel diversa non faccia qualcos'altro.

Se si desidera che i processi si alternino tra i cicli, ora è il momento di imparare interprocess communication.

+0

In generale, ci si può aspettare che il kernel sia "equo" durante la pianificazione dei processi. Ciò significa che, se il genitore e il figlio vengono eseguiti per un lungo periodo, entrambi otterranno approssimativamente la stessa quantità di tempo di elaborazione e nessuno dei due dovrà attendere troppo a lungo tra le attivazioni. Ovviamente, le scale temporali qui considerate sono molto più grandi di un paio di iterazioni di loop. – MicroVirus

1

Il processo principale non sta cedendo il controllo immediatamente e il ciclo for viene eseguito così velocemente da essere eseguito prima che il secondo processo venga pianificato. Quando eseguo il codice ottengo stampe non sequenziali, ma il comportamento dipende dal sistema.

A volte è utile inviare comandi sleep() quando si gioca con fork(). Prova questo codice ...

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 

#define MAX_COUNT 10 
int main(void) 
{ 
    pid_t pid; 
    int i; 
    fork(); 

    pid = getpid(); 

    srand(pid); // Make sure each process has a different seed 

    for(i = 1; i <= MAX_COUNT; i++) 
    { 
    printf("PID = %d, i = %d\n", pid, i); 

    // Sleep 1-3 seconds. 
    unsigned int sleep_seconds = rand() % 3 + 1; 
    sleep(sleep_seconds); 
    } 
} 
Problemi correlati