PDA

View Full Version : [C-unix]PIPE, sbaglio qualcosa?


MEMon
06-03-2008, 14:12
1 #include <fcntl.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #define TRUE 1
6 #define FALSE 0
7 #define ERROR -1
8 #define PERM 0644 //Definisce i permessi per la creazione dei file:rw per l'user e r per il gruppo e gli altri
9 #define N_ARGS 2 //Numero di argomenti atteso
10 #define MSGSIZE 20
11
12 void error(char * error, int ex_value){
13 perror(error);
14 exit(ex_value);
15 }
16
17 int checkArgs(int n){
18 if(n-1!=N_ARGS) return ERROR;
19 return TRUE;
20 }
21
22
23 main(int argc, char *argv[]){
24
25 int nr,wr,piped[2];
26 int pid, ppid;
27 int cycle;
28 char buffer[MSGSIZE];
29
30 if((checkArgs(argc))<0) error("Numero argomenti inatteso", 1);
31 if(pipe(piped)<0) error("Errore pipe: ", 2);
32 if((pid=fork())<0) error("Errore fork: ",3);
33 cycle=atoi(argv[2])+1;
34 if(pid==0){
35 //------- FIGLIO --------
36 ppid=getppid();
37 close(piped[1]); //Figlio: chiusura lato scrittura
38 while((nr=read(piped[0],buffer,MSGSIZE))>0){
39 printf("Ricevuto: %s\n", buffer);
40 }
41 printf("PIPE senza scrittore: exit\n");
42 exit(0);
43 }
44 else{
45 //------- PADRE ---------
46 close(piped[0]); //Padre: chiusura lato lettura
47 while(cycle--) write(piped[1],argv[1],MSGSIZE);
48 close(piped[1]);
49 exit(0);
50 }
51 }

In teoria il programma dovrebbe terminare quando ANCHE il padre chiude il lato di scrittura della pipe. In quel momento la read dovrebbe "sbloccarsi".
Funziona, cioà mi stampa a video "PIPE senza scrittore: exit" ma sembra però che non termini realmente finchè non premo INVIO.
Da cosa è dato questo comportamento? C'è qualcosa di strano nel codice?

MEMon
06-03-2008, 14:28
Se nel padre, dopo che chiude il lato di scrittura, aggiungo un wait() allora funziona come dovrebbe, come mai?
Tra l'altro senza wait il figlio legge meno messaggi di quelli che il padre spedisce, in teoria la pipe, essendo FIFO non dovrebbe cacciarli fuori tutti, a partire dal primo scritto?

Non capisco... :confused:

MEMon
06-03-2008, 14:37
Oddio rimane zombie senza wait?
Zombie, mamma mia che roba.

MEMon
06-03-2008, 14:43
Eh si avevo creato proprio un bello zombie.

ilsensine
06-03-2008, 14:53
Il programma termina correttamente, ma sul tuo sistema evidentemente il child termina dopo il padre. Quindi dopo che il programma si è chiuso il child stampa le sue ultime cose, che ti mandano a capo la console e...ti danno l'impressione che il programma non è ancora finito. Quando premi invio il prompt viene stampato nuovamente e...ti sembra che il programma è finito ora.
La wait semplicemente impedisce al padre di terminare prima del child; sostituiscila per prova con una sleep(1) e verdrai che è così!

MEMon
06-03-2008, 14:57
Allora si, non mi ero accorto che la console me la mette subito appena finisce il padre e quindi quando finisce il figlio la console me l'ha già ridata, ma si trova prima delle stampe del figlio.

Ad ogni modo, essendo che senza wait il padre finisce prima del figlio, creo uno zombie vero?

MEMon
06-03-2008, 15:03
Altra cosa, come mai le stampe che metto nel padre vengono visualizzate solo dopo che il figlio finisce?
Edit:mi sbagliavo.

ilsensine
06-03-2008, 15:20
Ad ogni modo, essendo che senza wait il padre finisce prima del figlio, creo uno zombie vero?
No. Uno zombie si crea se il child termina, ma il padre rimane in esecuzione senza chiamare wait/waitpid.
Se anche il padre termina, senza chiamare wait/waitpid, penserà init a ripulire lo zombie.

MEMon
06-03-2008, 15:23
Ok grazie, quindi in questo caso il processo figlio viene chiamto orfano visto che il padre termina prima del figlio?

ilsensine
06-03-2008, 15:39
Ok grazie, quindi in questo caso il processo figlio viene chiamto orfano visto che il padre termina prima del figlio?
Viene "reparented" al processo con pid 1 (tipicamente init), che ne diventa il "parent".

MEMon
06-03-2008, 20:13
Se devo inviare su una pipe un INT utilizzando wirte, come posso fare?
Una cosa così funziona?


int i=10;
write(pipe[0],&i,sizeof(int))


Lo chiedo perchè sembra andare ma ho degli strani casini nel programma e non vorrei fosse questo...

ilsensine
06-03-2008, 22:45
A funzionare funziona; la parte che legge deve essere certa che sta per leggere 4 byte, e che quei 4 byte sono il tuo int.

MEMon
06-03-2008, 22:46
Allora ho dei casini vari nel programma, se te lo posto mi ci dai un'occhiata?

ilsensine
06-03-2008, 22:53
non ci contare troppo...postalo cmq

MEMon
06-03-2008, 22:53
Ma non capisco, quando apro una pipe da utilizzare fra due processi, devo OBBLIGATORIAMENTE chiudere il lato della pipe che non uso?

MEMon
06-03-2008, 22:57
non ci contare troppo...postalo cmq

No va beh non vorreis tressarti perchè sono tante righe, comunque non riesco a capire bho...
Ho aperto N pipe, e ho creato N figli, ogni coppia di figli utilizzia una pipe, e N-2 pipe non le usa, come mi devo comportare, le pipe che non usa un figlio le devo chiudere sia in lettura che scrittura?

MEMon
06-03-2008, 23:03
Edit:sono un cojote, non avevo creato tutte le pipes... sarà la stanchezza? :cry:

ilsensine
06-03-2008, 23:26
--edit