Ordine del fork()

di il
3 risposte

Ordine del fork()

So che il processo padre e figlio vengono eseguiti insieme in un fork
percio' non si puo' stabilire se nell'output verra' fuori prima padre o figlio.
Tuttavia dopo aver fatto vari run del programma il processo padre iniziale mi viene fuori sempre per primo e per il 95% dei casi come secondo mi viene fuori il figlio del padre del padre, potreste dirmi il motivo? Ho fatto ricerche su internet ma non sono riuscito a trovare la risposta per questo ho deciso di chiederlo a voi. Vi posto il codice:

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

int main()
{
char* s=(char*)malloc(sizeof(char)*8);
char* c="123";
int i,j=0;
for(i=0;i<3;i++)
if(fork())
s[j++]=c;
s[j]='\0';
printf("%s\n",s);
}

Mi escono i seguenti output:
123
12
13
23
1
2
3

oppure

123
12
23
2
13
3
1

etc etc ma sempre 123 iniziale e per il 95% dei casi 12 come seconda riga.
Grazie a chi mi rispondera'!

3 Risposte

  • Re: Ordine del fork()

    Non c'è un vero motivo, lo scheduler decide di far proseguire il padre o il figlio in base a diversi fattori.
    Però in questo caso sembra più che altro che il tuo codice non vada bene, per favore lo metteresti all'interno degli appositi tag code e identato in modo da poterlo analizzare bene?
    Cosi a prima vista per ogni ciclo il padre crea un figlio e il padre memorizza 1, poi qui si innescano due processi, entrambi richiamano una fork e i due padri ora hanno 12 e 13 entrambi poi si siddividono in altri due processi diventando quattro con risultato 124 135 o in formato diverso dipendente dal tempo di esecuzione.
    Il problema è che la tua stringa arriva solo a 3.

    Io proverei con :
    
    char s[80]; //allocazione dinamica inutile in questo caso
    // s[j++]=c[i];cambialo in
    s[j++] = i + '0';
    
  • Re: Ordine del fork()

    vbextreme ha scritto:


    Non c'è un vero motivo, lo scheduler decide di far proseguire il padre o il figlio in base a diversi fattori.
    Però in questo caso sembra più che altro che il tuo codice non vada bene, per favore lo metteresti all'interno degli appositi tag code e identato in modo da poterlo analizzare bene?
    Cosi a prima vista per ogni ciclo il padre crea un figlio e il padre memorizza 1, poi qui si innescano due processi, entrambi richiamano una fork e i due padri ora hanno 12 e 13 entrambi poi si siddividono in altri due processi diventando quattro con risultato 124 135 o in formato diverso dipendente dal tempo di esecuzione.
    Il problema è che la tua stringa arriva solo a 3.

    Io proverei con :
    
    char s[80]; //allocazione dinamica inutile in questo caso
    // s[j++]=c[i];cambialo in
    s[j++] = i + '0';
    
    Alla fine dell'ultimo ciclo i processi sono 8
    c'e' ne anche uno di solo \n
    che ovviamente avolte viene stampato semplicemente tornando a capo di riga ma siccome non e' memorizzato niente non si puo' vedere.
    Il codice memorizza nel s[j++] il corrispondente valore nella posizione di c solo quando il processo e' diverso dal figlio.
    quindi il processo nonno sarebbe 123 il nipote del nonno 12 etc etc per tutti i 8 rami di processi, il processo in cui non viene visualizzato nulla e' il figlio del figlio del figlio, che risultando sempre pid 0 non immagazzinava mai niente.

    riscrivo il codice:
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    char* s=(char*)malloc(sizeof(char)*8);
    char* c="123";
    int i,j=0;
    
    for(i=0;i<3;i++){
    
       if(fork())
    s[j++]=c[i];
    }
    
    s[j]='\0';
    printf("%s\n",s);
    }
  • Re: Ordine del fork()

    Mi ero dimenticato un passaggio.
    comunque il codice che hai posato sarebbe piu elegante scritto:
    
    int main()
    {
    	char s[8];
    	int i;
    	int j = 0;
    
    	for(i = 0; i < 3; ++i)
    		if( fork() )
    			s[j++]= i + '1';
    
    	s[j]='\0';
    	printf("%s\n",s);
    	
    	return 0;
    }
    
    se lo compili vedi che fa la stessa identica cosa.
    Ricordati che il padre di tutti dovrebbe essere l'ultimo ad essere terminato, ancor meglio terminare nipote,figlio,padre.
Devi accedere o registrarti per scrivere nel forum
3 risposte