Newsgroup: it.comp.lang.c
Titolo: Processi child e IPC

Ciao a tutti,
devo sviluppare un programmino che testi le funzionalità della comunicazione
inter-processo, e mi sto imbattendo in un problema abbastanza strano.
Il mio codice è abb standard ed è il seguente:
...
pid = fork();
 if ( pid < 0)
 {
  perror("error in fork");
  exit (1);
 }//if
 if (0 == pid)
 {
 /** Child **/
..codice..
printf ("Processo figlio");
..codice..
}//if
else
{
 /** Parent **/
printf("Processo padre");
}//else
Il problema che incontro è che una volta compilato e eseguito la printf del
processo figlio non viene eseguita.
Mentre quella del padre si. Aggiungo che nel processo figlio effetivamente è
presente del codice (statement e istruzioni standard che inizializzano pipe
e message queue, però anche se la printf è la prima istruzione del branch
child non viene eseguita (huh?). Qualcuno sa indicarmi come posso debuggare
questo tipo di problematica? o ancor meglio come risolverla? (non ottengo
messaggi di errore di nessun tipo e anche se redirigo il programma su di un
file mi ritrovo soltanto il risultato della printf del padre).
Aggiungo due domande inerenti all'implementazione di un codice di questo
tipo:
1) se devo generare n figli che comunicano con il loro padre aggiungo una
bella for prima della fork; ma poichè la fork ritorna due volte (una nel
figlio e una nel padre), il codice del padre verrà eseguito n volte? Ad. es.
se il padre dovesse funzionare da 'hub' per i figli (cioè ricevere messaggi,
eventualmente elaborarli e rispedirli ai figli) il codice sarebbe cmq
corretto(mi immagino una struttura client server standard, con 1 e un solo
server e n processi che gestiscono gli n client)?
2) (questa domanda, forse, mi risolverebbe quella precedente) come posso
sincornizzare i processi? tipo il parent resta in attesa che tutti i figli
partano e poi inizia ad elaborare e i figli restano in attesa di essere
partiti tutti prima di iniziare l'elaborazione. (se ci sono esempi o doc da
vedere va benissimo, non intendo farmi spiegare la rava e la fava, mi basta
una risposta per keywords tipo usa questo o quest'altro, poi approfondisco
da me :)
3) domandina di design: è corretto pensare di utilizzare le pipe per la
comunicazione padre-figlio e le message queue per figlio-figlio? o è
preferibile utilizzare soltanto message queue?
So che sono stato un po' prolisso, chiedo venia in anticipo e ringrazio
chiunque possa aiutarmi.
Alexio

 chiunque possa aiutarmi.
Ciao!
--
Luigi Mantellini
Per il pessimista il bicchiere è mezzo vuoto,
per l'ottimista è mezzo pieno,
per un ingegnere è semplicemente sovradimensionato rispetto l'uso.

 Luigi Mantellini
Alexio

Per la cronaca, il sincronismo l'otterresti con dei semafori interi... che
in Unix non ci sono! Quindi con il trucco delle pipe hai implementato un
semaforo intero.
Child:
    sem_signal(shared_Sem);
che diventa
    write(shared_Sem[0], &c, 1);
Parent:
    for (i=0; i<n; i++)  {
        sem_wait(shared_Sem);
    }
che diventa
    for (i=0; i<n; i++) {
        read(shared_Sem[1], &c, 1);
    }
Se usi librerie (tipo cthreads od altro), il tutto potrebbe essere
implementato con semafori basati su altri costrutti (tipo busy form
waitng... etc...), senza che questi tocchino (almeno a prima vista) le pipe.
Preferisco che le cose siano fatte capendo il perchč...
NB.: Non mi ricordo se nelle pipe 1 era la lettura o la scrittura... non ho
manuali a portata di mano... quindi basta cambiare eventualmente l'indice.
Scusa, ma la mia memoria fa spesso cilecca!
--
Luigi Mantellini
Per il pessimista il bicchiere č mezzo vuoto,
per l'ottimista č mezzo pieno,
per un ingegnere č semplicemente sovradimensionato rispetto l'uso.

 semaforo intero.
Ciao!
se non sbaglio lo standard POSIX prevede l'implementazione della libreria
semaphore.h, o no?
In tal caso potrei usare quella (o in ogni caso dovrebbero esserci le varie
semget, semop e semctl).
Ora come ora i processi si sincronizzano con le pipe (ne ho create 2 una in
cui i processi scrivono e leggono
i bytes come da te suggerito, e una in cui il parent scrive n bytes per dire
ai child che sono tutti attivi), quindi
potrei lasciarlo cosě, ma visto che il fine di questo progettino č didattico
non vorrei cappellare reinventando
l'acqua calda simulando un semaforo con le pipe...
Il problema che avevo ieri relativo al flushing del buffer l'ho risolto
'semplicemente' forzando \n in ogni printf...
il che conferma che la tua intuizione era corretta :)
Domandona: usando le message queue mi capita di 'saturare' le risorse del
kernel e dopo un po' di avvii
mi stampa a video un'errore tipo 'not space on device' e non mi inizializza
il canale di comunicazione:
c'č un modo di fare 'garbage collection' e liberare spazio nel kernel?
(considerato che ricompilo almeno
10 volte ogni ora, dopo un'oretta devo riavviare il pc per liberare lo
spazio...snervante e in ogni caso non
mi va che il mio programmino sporchi cosě senza manco pulire il water :)
Ciao e grazie
alexio


Prego, mi dispiace di non poterti aiutare fino in fondo! Ma non è il mio
settore.
Ciao
--
Luigi Mantellini
Per il pessimista il bicchiere è mezzo vuoto,
per l'ottimista è mezzo pieno,
per un ingegnere è semplicemente sovradimensionato rispetto l'uso.


Alexio