Newsgroup: it.comp.lang.c
Titolo: Ma perche' la fork() rompe i blocchi?

Piu' o meno  e' noto che la caratteristica peculiare della fork() e' la
seguente: non e' possibile stabilire se il processo padre verra'
eseguito prima del processo figlio.
Benissimo. Quello che mi pare pero' e' che non solo non si sa chi venga
eseguito prima, ma che il padre ed il figlio possano essere esguiti "un
pezzo l'uno ed un pezzo l'altro"
Per esempio prendiamo questo programmino tirato giu' da un libro ("Linux
programming" della QUE) il cui sorgente sta tra i due tratteggi:
----------------------------------------------------------------------------------------------
/*
 * child.c - Simple fork usage
 */
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    pid_t child;
    if((child = fork()) == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    } else if(child == 0) {
        puts("in child");
        printf("\tchild pid = %d\n", getpid());
        printf("\tchild ppid = %d\n", getppid());
        exit(EXIT_SUCCESS);
    } else {
        puts("in parent");
        printf("\tparent pid = %d\n", getpid());
        printf("\tparent ppid = %d\n", getppid());
    }
    exit(EXIT_SUCCESS);
}
-------------------------------------------------------------------------------------------------
ora il mio output e':
# ./child 
in parent
	parent pid = 1629
	parent ppid = 1412
in child
	child pid = 1630
	child ppid = 1
che a me andrebbe anche bene, ma l'output che viene riportato
dall'autore del libro (ovviamente i numeri sono diversi) e' il seguente:
# ./child 
in parent
	child pid = 1150
	child ppid = 1149
	parent pid = 1149
	parent ppid = 706
dacche' sembra che prima venga eseguito una parte del processo padre (e'
la stringa "in parent") poi viene eseguito il porcesso figlio per
intero, e poi di nuovo il processo padre. E NON e' un errore di stampa,
l'autore fa proprio notare che la prima riga viene dal padre, le
seguenti 3 dal figlio, le rimanenti 2 ancora dal padre.  
Ma perche? Io mi aspetterei che, d'accordo che non si sa chi venga
prima, ma che quando un processo parte vegna prima terminato quel
processo e poi venga fatto partire l'altro, o detto in altra maniera
estremamente piu' grezza: che i blocchi di codice tra parentesi graffe,
quando compilati e passati in ram, rimangano "tutti attaccati" per cui
le parti del programma tra le graffe vengano eseguiti per l'appunto "in
blocco".
Qui invece sembrerebbe di no e la cosa mi perplime. Qualcuno sa darmi
una spiegazione?
Spero di essermi spiegato,
grazie per l'attenzione,
b.

 eseguito prima del processo figlio.
it.comp.os.linux.development
-- 
Posted from  [80.105.34.80] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG


e' una questione di scheduling fra processi, le operazioni svolte
dal processo padre e figlio non sono "atomiche" e possono
interfogliarsi ( chiedo scusa per il termine ). ;)
Per ottenere una forma di sincronizzazione puoi usare wait() oppure
waitpid().
Ciao ciao.

 Ciao ciao.
Spiegazione chiarissima,
grazie mille,
b.

 una spiegazione?
Si, e la cosa è molto semplice. In un sistema operativo il processore deve
eseguire i processi. E, in un monoprocessore può essere eseguito un solo
processo alla volta per certi quanti di tempo. Ora però devi capire che se
un processo deve ad esempio fare qualcosa come , che so, scrivere su un file
delle stringhe quando è in esecuzione comincia a scrivere; ma ovviamente in
un sistema ci sono miriadi di processi che chiedono l'utilizzo del
processore e ad esempio se un processo di sistema importante ha bisogno in
quel momento del processore, che fa? aspetta che il processo in esecuzione
termini? e se deve scrivere 1 GB di caratteri cosa fa, si va a prendere un
caffè?
Ecco perchè quindi esiste il cosiddetto Prerilascio del processore, che
rimette in stato di pronto l'attuale processo(dopo aver salvato tutti i
dati) fa partire quello che ha un priorità maggiore(che a sua volta può
essere prerilasciato) e via dicendo.... per l'utente sembra che sia tutto
contemporaneo , ma in realtà non è così(ovviamnete lo scheduling del
processore ha varie politiche di gestione, ma nn credo ora interessi).
Quindi quello che tu dici
                "che i blocchi di codice tra parentesi graffe,
                 quando compilati e passati in ram, rimangano "tutti
attaccati" per cui
                 le parti del programma tra le graffe vengano eseguiti per
l'appunto "in
                 blocco"
non può accadere mai, a meno di una opportuna codifica di semafori o
protocolli di lock/unlock. Il processore può anche eseguire una sola
istruzione e fermarsi per poi ricominciare da quella successiva in un
secondo momento.Il tutto si risolverebbe se il blocco constasse di una
singola istruzione intrinsecamente indivisibile, ma non è questo il caso.
Ciao ,
Fly