Lab. di Sistemi Operativi
Esercitazioni proposte per la lezione del 13 maggio 2011
Utilizzando il compilatore gcc in Linux e disponendosi in gruppi di due persone per ogni PC del labora- torio.
1. Utilizzare un file a parte (es91b.c) in cui spostare la funzione figlio e modificare di conseguenza il Makefile
2. Invocare la system call pipe e visualizzare il valore dei file descriptor generati (es92.c).
3. Modificare es92.c in modo da immettere qualche carattere nel lato di scrittura e prelevarlo da quello di lettura.
4. Modificando es92.c, verificare cosa succede se si tenta di utilizzare la pipe in direzione opposta.
5. Verificare cosa succede se si tenta di scrivere su una pipe con il lato di lettura chiuso.
6. Verificare con un nuovo sorgente (es93.c) la capacit`a della pipe scrivendo su di essa fino alla satu- razione.
7. (20 minuti) es94.c Creazione di N-pipe, con N valore del primo argomento. Allocare dinamicamente la memoria per i 2N file descriptor (man malloc) e riempire l’array con i file descriptor ritornati dalla pipe(). Visualizzarne i valori su stdout.
8. (20 minuti) es95.c Una pipe come strumento di comunicazione fra processo padre e figlio. Passare un carattere, un intero ed una struttura da padre a figlio.
9. (20 minuti) es96.c Una pipe per N processi figli. Far creare al padre N processi (con N valore del primo argomento) ed utilizzare una singola pipe per passare una struttura di dati da ogni figlio al padre.
10. (20 minuti) es97.c N pipe per N processi figli. Far creare al padre N processi ed utilizzare una pipe per ogni processo figlio. Leggere le strutture in modo ordinato, prima dall’ultimo figlio poi dal penultimo e cos`ı via fino al primo.
11. (20 minuti) es98.c N pipe per N processi figli. Far creare al padre N processi ed utilizzare una pipe per ogni processo figlio ma diretta dal padre verso il figlio. Ogni figlio attende un carattere poi stampa il proprio pid su stdout. Il padre manda un carattere ad ogni figlio dall’ultimo al primo.
12. (20 minuti) es99.c N pipe per N+1 processi figli. Far creare al padre N processi ed utilizzare una pipe per collegare ogni processo figlio al successivo. Il primo processo figlio emette il proprio pid poi invia un carattere al secondo che, dopo aver stampato il proprio pid, attiva il successivo ...
13. (20 minuti) es9A.c N pipe per N+1 processi. Come prima ma il primo processo a stampare il pid `e l’ultimo creato
Soluzione
Esercitazioni proposte per la lezione del 13 maggio 2011
Utilizzando il compilatore gcc in Linux e disponendosi in gruppi di due persone per ogni PC del labora- torio.
1. Utilizzare un file a parte (es91b.c) in cui spostare la funzione figlio e modificare di conseguenza il Makefile
Soluzione:
/∗ f i l e : e s 9 1 . c
∗ j o b : f o r k ( ) m u l t i p l a
∗/
#include <s y s / t y p e s . h>
#include <u n i s t d . h>
#include < s t d l i b . h>
#include <s t d i o . h>
#include < s t r i n g . h>
#include <s y s / w a i t . h>
char s t r i n g a [ 2 5 6 ] ;
/∗ P r o t o t i p o d e l l a f u n z i o n e f i g l i o , a n c o r a i n e s 9 3 . c ∗/
i n t f i g l i o ( i n t argomento ) ;
i n t main ( i n t a r g c , char ∗∗ a r g v ) { i n t n f i g l i ; /∗ N ∗/
i n t i n d i c e ; /∗ i n d i c e d i c r e a z i o n e ∗/
i n t p i d ; /∗ p r o c e s s i d e n t i f i e r ∗/
i n t s t ; /∗ e x i t s t a t u s ∗/
i f ( a r g c <2) {
s n p r i n t f ( s t r i n g a , 2 5 6 , ” Uso : %s N\n” , a r g v [ 0 ] ) ; w r i t e ( 2 , s t r i n g a , s t r l e n ( s t r i n g a ) ) ;
return ( 1 ) ; } e l s e {
n f i g l i =a t o i ( a r g v [ 1 ] ) ; }
f o r ( i n d i c e =0; i n d i c e < n f i g l i ; i n d i c e ++) { p i d=f o r k ( ) ;
switch ( p i d ) {
case 0 : /∗ f i g l i o ∗/
/∗ c h i a m a t a a l l a f u n z i o n e f i g l i o
∗ e r e c u p e r o d e l v a l o r e d i
∗ r i t o r n o ∗/
return ( f i g l i o ( i n d i c e ) ) ; case −1: /∗ e r r o r e ∗/
s n p r i n t f ( s t r i n g a , 2 5 6 , ” E r r o r e a l l a %d−ma f o r k \n” , i n d i c e ) ; w r i t e ( 2 , s t r i n g a , s t r l e n ( s t r i n g a ) ) ;
return ( 1 ) ; /∗ t e r m i n a z i o n e p a d r e ∗/
d e f a u l t : /∗ padre , c o n t i n u a ∗/
s n p r i n t f ( s t r i n g a , 2 5 6 , ” C r e a t o f i g l i o %d con p i d %d\n” , i n d i c e , p i d ) ;
w r i t e ( 1 , s t r i n g a , s t r l e n ( s t r i n g a ) ) ; }
}
/∗ i l p a d r e a r r i v a q u i dopo l e N c r e a z i o n i ∗/
f o r ( i n d i c e =0; i n d i c e < n f i g l i ; i n d i c e ++) {
/∗ l ’ o r d i n e i n c u i i f i g l i t e r m i n a n o NON e ’ p r e v e d i b i l e ,
∗ q u i n d i i l v a l o r e r e c u p e r a t o a l l a i −esima i t e r a z i o n e
∗ non n e c e s s a r i a m e n t e s i r i f e r i s c e a l l ’ i −esimo
∗ f i g l i o . ∗/
p i d=w a i t (& s t ) ;
s n p r i n t f ( s t r i n g a , 2 5 6 , ” I l f i g l i o con p i d %d r i t o r n a %d\n” , pid ,WEXITSTATUS( s t ) ) ;
w r i t e ( 1 , s t r i n g a , s t r l e n ( s t r i n g a ) ) ; }
return ( 0 ) ; }
/∗ f i l e : e s 9 1 b . c
∗ j o b : f u n z i o n e f i g l i o
∗/
#include <u n i s t d . h>
#include < s t r i n g . h>
#include <s t d i o . h>
/∗ s t r i n g a a ’ a n c o ra a c c e s s i b i l e ( g l o b a l e ) ma i l
∗ c o m p i l a t o r e non sa c o s a s i a , i s t r u i a m o l o i n m e r i t o ∗/
extern char s t r i n g a [ ] ;
/∗ A t t e n z i o n e : l a d e f i n i z i o n e p r e c e d e n t e e ’ d i v e r s a da
∗ e x t e r n c h a r ∗ s t r i n g a i n q u a n t o i l s i m b o l o ” s t r i n g a ”
∗ s i r i f e r i s c e a l l ’ i n d i r i z z o d e l primo c a r a t t e r e
∗ d e l l ’ a r r a y e non a l l ’ i n d i r i z z o d e l p u n t a t o r e ad
∗ e s s o . In a l t r e p a r o l e , i l c o m p i l a t o r e d e v e s a p e r e
∗ che s t r i n g a e ’ un a r r a y e non un p u n t a t o r e ( s t e s s o
∗ t i p o ma s t o r a g e c l a s s d i f f e r e n t e ) ∗/
/∗ Corpo d e l l a f u n z i o n e f i g l i o i n e s 9 3 b . c ∗/
i n t f i g l i o ( i n t argomento ) {
s n p r i n t f ( s t r i n g a , 2 5 6 , ” F i g l i o con i n d i c e %d\n” , argomento ) ; w r i t e ( 1 , s t r i n g a , s t r l e n ( s t r i n g a ) ) ;
return ( 0 ) ; }
#! / b i n /make −f
# f i l e : M a k e f i l e a l l : e s 9 1
# R i c o r d a r s i l a l i n e a vuota come s e p a r a t o r e
# f o r m a t o d e l l a r e g o l a = o b i e t t i v o : d i p e n d e n z e e s 9 1 : e s 9 1 . c e s 9 1 b . c
g c c −Wall −o e s 9 1 e s 9 1 . c e s 9 1 b . c
# R i c o r d a r s i d e l t a b a l l ’ i n i z i o d i o g n i comando
# f i n e f i l e
2. Invocare la system call pipe e visualizzare il valore dei file descriptor generati (es92.c).
Soluzione:
/∗ f i l e : e s 9 2 . c
∗ j o b : p i p e
∗/
#include <u n i s t d . h>
#include <s t d i o . h>
#include < s t r i n g . h>
char msg [ 2 5 6 ] ;
i n t main ( i n t a r g c , char ∗∗ a r g v ) {
i n t p f d [ 2 ] ; /∗ c o n t e n i t o r e p e r i 2 f d ∗/
i f ( p i p e ( p f d ) ! = 0 ) {
w r i t e ( 2 , ” E r r o r e i n p i p e ( ) \ n” , 1 7 ) ; return ( 1 ) ;
}
s n p r i n t f ( msg , s i z e o f ( msg ) , ” p f d [0]=%d , p f d [1]=%d\n” , p f d [ 0 ] ,
p f d [ 1 ] ) ;
w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; return ( 0 ) ;
}
3. Modificare es92.c in modo da immettere qualche carattere nel lato di scrittura e prelevarlo da quello di lettura.
Soluzione:
/∗ f i l e : e s 9 2 b . c
∗ j o b : p i p e
∗/
#include <u n i s t d . h>
#include <s t d i o . h>
#include < s t r i n g . h>
char msg [ 2 5 6 ] ; char msg2 [ 2 5 6 ] ;
i n t main ( i n t a r g c , char ∗∗ a r g v ) {
i n t p f d [ 2 ] ; /∗ c o n t e n i t o r e p e r i 2 f d ∗/
i f ( p i p e ( p f d ) ! = 0 ) {
w r i t e ( 2 , ” E r r o r e i n p i p e ( ) \ n” , 1 7 ) ; return ( 1 ) ;
}
s n p r i n t f ( msg , s i z e o f ( msg ) , ” p f d [0]=%d , p f d [1]=%d\n” , p f d [ 0 ] ,
p f d [ 1 ] ) ;
w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; /∗ su s t d o u t ∗/
w r i t e ( p f d [ 1 ] , msg , s t r l e n ( msg ) ) ; /∗ su msg−>p i p e ∗/
r e a d ( p f d [ 0 ] , msg2 , s i z e o f ( msg2 ) ) ; /∗ da p i p e −>msg2 ∗/
w r i t e ( 1 , msg2 , s t r l e n ( msg2 ) ) ; /∗ msg2 su s t d o u t ∗/
return ( 0 ) ; }
4. Modificando es92.c, verificare cosa succede se si tenta di utilizzare la pipe in direzione opposta.
Soluzione:
/∗ f i l e : e s 9 2 c . c
∗ j o b : p i p e
∗/
#include <u n i s t d . h>
#include <s t d i o . h>
#include < s t r i n g . h>
char msg [ 2 5 6 ] ; char msg2 [ 2 5 6 ] ;
i n t main ( i n t a r g c , char ∗∗ a r g v ) {
i n t p f d [ 2 ] ; /∗ c o n t e n i t o r e p e r i 2 f d ∗/
i n t nw , nr ; /∗ r i t o r n i d i r e a d e w r i t e ∗/
i f ( p i p e ( p f d ) ! = 0 ) {
w r i t e ( 2 , ” E r r o r e i n p i p e ( ) \ n” , 1 7 ) ; return ( 1 ) ;
}
s n p r i n t f ( msg , s i z e o f ( msg ) , ” p f d [0]=%d , p f d [1]=%d\n” , p f d [ 0 ] ,
p f d [ 1 ] ) ;
w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; /∗ su s t d o u t ∗/
/∗ A t t e n z i o n e a l l ’ i n v e r s i o n e [0] < − >[1] ∗/
nw=w r i t e ( p f d [ 0 ] , msg , s t r l e n ( msg ) ) ; /∗ su msg−>p i p e ∗/
nr=r e a d ( p f d [ 1 ] , msg2 , s i z e o f ( msg2 ) ) ; /∗ da p i p e −>msg2 ∗/
w r i t e ( 1 , msg2 , s t r l e n ( msg2 ) ) ; /∗ msg2 su s t d o u t ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) , ”nw= %d , nr= %d\n” , nw , nr ) ;
w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; /∗ su s t d o u t ∗/
return ( 0 ) ; }
5. Verificare cosa succede se si tenta di scrivere su una pipe con il lato di lettura chiuso.
Soluzione:
/∗ f i l e : e s 9 2 d . c
∗ j o b : p i p e
∗/
#include <u n i s t d . h>
#include <s t d i o . h>
#include < s t r i n g . h>
char msg [ 2 5 6 ] ; char msg2 [ 2 5 6 ] ;
i n t main ( i n t a r g c , char ∗∗ a r g v ) {
i n t p f d [ 2 ] ; /∗ c o n t e n i t o r e p e r i 2 f d ∗/
i n t nw , nr ; /∗ r i t o r n i d i r e a d e w r i t e ∗/
i f ( p i p e ( p f d ) ! = 0 ) {
w r i t e ( 2 , ” E r r o r e i n p i p e ( ) \ n” , 1 7 ) ; return ( 1 ) ;
}
s n p r i n t f ( msg , s i z e o f ( msg ) , ” p f d [0]=%d , p f d [1]=%d\n” , p f d [ 0 ] ,
p f d [ 1 ] ) ;
w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; /∗ su s t d o u t ∗/
c l o s e ( p f d [ 0 ] ) ; /∗ c h i u d o l a t o l e t t u r a ∗/
nw=w r i t e ( p f d [ 1 ] , msg , s t r l e n ( msg ) ) ; /∗ su msg−>p i p e ∗/
/∗ q u e s t a s y s c a l l s c a t e n a un s e g n a l e d i
∗ ” b r o k e n p i p e ” che p r o v o c a l a t e r m i n a z i o n e d e l
∗ p r o c e s s o ∗/
nr=r e a d ( p f d [ 0 ] , msg2 , s i z e o f ( msg2 ) ) ; /∗ da p i p e −>msg2 ∗/
w r i t e ( 1 , msg2 , s t r l e n ( msg2 ) ) ; /∗ msg2 su s t d o u t ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) , ”nw= %d , nr= %d\n” , nw , nr ) ;
w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; /∗ su s t d o u t ∗/
return ( 0 ) ; }
6. Verificare con un nuovo sorgente (es93.c) la capacit`a della pipe scrivendo su di essa fino alla saturazione.
Soluzione:
/∗ f i l e : e s 9 3 . c
∗ j o b : d i m e n s i o n e b u f f e r p i p e
∗/
#include <u n i s t d . h>
#include < f c n t l . h>
#include <s t d i o . h>
#include < s t r i n g . h>
char msg [ 2 5 6 ] ;
i n t main ( i n t a r g c , char ∗∗ a r g v ) {
i n t p f d [ 2 ] ; /∗ c o n t e n i t o r e p e r i 2 f d ∗/
i n t c o u n t ; /∗ c o n t a t o r e ∗/
i n t nw ; /∗ r i t o r n o d e l l a w r i t e ∗/
i f ( p i p e ( p f d ) ! = 0 ) {
w r i t e ( 2 , ” E r r o r e i n p i p e ( ) \ n” , 1 7 ) ; return ( 1 ) ;
}
/∗ S e t p f d [ 1 ] t o non b l o c k i n g mode ∗/
i f ( f c n t l ( p f d [ 1 ] , F SETFL ,O NONBLOCK) ! = 0 ) { w r i t e ( 2 , ” E r r o r e i n f c n t l ( ) \ n” , 1 8 ) ; return ( 1 ) ;
}
/∗ A t t e n z i o n e : s e non a v e s s i m o m o d i f i c a t o i l f l a g
∗ O NONBLOCK, i l p r o c e s s o c o r r e n t e s i s a r e b b e b l o c c a t o
∗ i n d e f i n i t a m e n t e i n a t t e s a d i s p a z i o n e l l a p i p e ,
∗ p r o v a r e p e r c r e d e r e r i m u o v e n t o f c n t l ( ) ∗/
f o r ( c o u n t =0; ; c o u n t++) { nw=w r i t e ( p f d [ 1 ] , ”A” , 1 ) ;
i f (nw! = 1 ) break ; }
s n p r i n t f ( msg , s i z e o f ( msg ) , ”Ho s c r i t t o %d c a r a t t e r i n e l l a p i p e \n” , c o u n t ) ;
w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; /∗ su s t d o u t ∗/
return ( 0 ) ; }
7. (20 minuti) es94.c Creazione di N-pipe, con N valore del primo argomento. Allocare dinamicamente la memoria per i 2N file descriptor (man malloc) e riempire l’array con i file descriptor ritornati dalla pipe(). Visualizzarne i valori su stdout.
Soluzione:
/∗ f i l e : e s 9 4 . c
∗ j o b : a r r a y d i p i p e
∗/
#include <u n i s t d . h>
#include <s t d i o . h>
#include < s t r i n g . h>
#include < s t d l i b . h>
char msg [ 2 5 6 ] ; i n t ∗ p f d s ;
i n t main ( i n t a r g c , char ∗∗ a r g v ) { i n t n p i p e ;
i n t i ;
i f ( a r g c <2) { /∗ c o n t r o l l o num a r g s ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” Uso : %s N\n” , a r g v [ 0 ] ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
n p i p e=a t o i ( a r g v [ 1 ] ) ;
i f ( npipe <=0) { /∗ c o n t r o l l o N ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
”N(%d ) non v a l i d o \n” , n p i p e ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
p f d s = m a l l o c ( 2 ∗ s i z e o f ( i n t ) ∗ n p i p e ) ; i f ( p f d s==NULL) { /∗ c o n t r o l l o m a l l o c ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” A l l o c a z i o n e f a l l i t a \n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
f o r ( i =0; i <n p i p e ; i ++) { /∗ p e r o g n i p i p e ∗/
/∗ c r e o l a c o p p i a d i f d s ∗/
i f ( p i p e (&( p f d s [ 2 ∗ i ] ) ) ! = 0 ) { /∗ e r r o r e ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” p i p e f a l l i t a i n %d\n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
} }
f o r ( i =0; i <n p i p e ; i ++) { /∗ p e r o g n i p i p e ∗/
/∗ stampo i f i l e d e s c r i p t o r ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) , ” p f d s [2∗%d+0]=%d , p f d s [2∗%d+1]=%d\n” , i , p f d s [ 2 ∗ i + 0 ] ,
i , p f d s [ 2 ∗ i + 1 ] ) ;
w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; /∗ su s t d o u t ∗/
}
return ( 0 ) ; }
8. (20 minuti) es95.c Una pipe come strumento di comunicazione fra processo padre e figlio. Passare un carattere, un intero ed una struttura da padre a figlio.
Soluzione:
/∗ f i l e : e s 9 5 . c
∗ j o b : p i p e f r a p r o c e s s i
∗/
#include <u n i s t d . h>
#include <s t d i o . h>
#include < s t r i n g . h>
typedef i n t p i p e t [ 2 ] ; /∗ t i p o p e r p i p e ∗/
char msg [ 2 5 6 ] ;
char ch ; /∗ c a r a t t e r e da i n v i a r e ∗/
i n t i n t e r o ; /∗ i n t e r o da i n v i a r e ∗/
s t r u c t {
i n t u n i n t ; char unchar ; char s t r i n g [ 1 6 ] ;
} s t r u t t u r a ; /∗ s t r u t t u r a da i n v i a r e ∗/
p i p e t p f d ; /∗ c o n t e n i t o r e p e r i 2 f d ∗/
i n t f i g l i o ( void ) ; /∗ f u n z i o n e f i g l i o ∗/
i n t main ( i n t a r g c , char ∗∗ a r g v ) { i f ( p i p e ( p f d ) ! = 0 ) {
w r i t e ( 2 , ” E r r o r e i n p i p e ( ) \ n” , 1 7 ) ; return ( 1 ) ;
}
switch ( f o r k ( ) ) {
case 0 : /∗ f i g l i o ∗/
return ( f i g l i o ( ) ) ; case −1:
break ; }
/∗ s o l o i l p a d r e a r r i v a q u i ∗/
ch= ’A ’ ;
i f ( w r i t e ( p f d [ 1 ] , & ch , s i z e o f ( ch ) ) ! = s i z e o f ( ch ) ) { s n p r i n t f ( msg , s i z e o f ( msg ) , ” E r r o r e i n v i o ch \n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
}
i n t e r o =1250;
i f ( w r i t e ( p f d [ 1 ] , & i n t e r o , s i z e o f ( i n t e r o ) ) ! = s i z e o f ( i n t e r o ) ) { s n p r i n t f ( msg , s i z e o f ( msg ) , ” E r r o r e i n v i o i n t e r o \n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
}
s t r u t t u r a . unchar= ’B ’ ; s t r u t t u r a . u n i n t =334;
s t r n c p y ( s t r u t t u r a . s t r i n g , ” Ciao Mondo ! ” , s i z e o f ( s t r u t t u r a . s t r i n g ) ) ; i f ( w r i t e ( p f d [ 1 ] , & s t r u t t u r a , s i z e o f ( s t r u t t u r a ) ) ! = s i z e o f ( s t r u t t u r a ) ) {
s n p r i n t f ( msg , s i z e o f ( msg ) , ” E r r o r e i n v i o s t r u t t u r a \n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
}
return ( 0 ) ; }
i n t f i g l i o ( ) { i n t nr ;
/∗ c h i u d o i l l a t o d i s c r i t t u r a ∗/
c l o s e ( p f d [ 1 ] ) ; /∗ c o s a s u c c e d e s e non l o f a c c i o ? ∗/
nr=r e a d ( p f d [ 0 ] , & ch , s i z e o f ( ch ) ) ; i f ( nr==s i z e o f ( ch ) ) {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” R i c e v o i l c h a r %c \n” , ch ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; } e l s e {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” Attendendo ch , o t t e n g o %d\n” , nr ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
}
nr=r e a d ( p f d [ 0 ] , & i n t e r o , s i z e o f ( i n t e r o ) ) ; i f ( nr==s i z e o f ( i n t e r o ) ) {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” R i c e v o l ’ i n t e r o %d\n” , i n t e r o ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ;
} e l s e {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” Attendendo i n t e r o , o t t e n g o %d\n” , nr ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
}
nr=r e a d ( p f d [ 0 ] , & s t r u t t u r a , s i z e o f ( s t r u t t u r a ) ) ; i f ( nr==s i z e o f ( s t r u t t u r a ) ) {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” R i c e v o l a s t r u t t u r a : \ n%c \n%d\n%s \n” , s t r u t t u r a . unchar ,
s t r u t t u r a . u n i n t , s t r u t t u r a . s t r i n g ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; } e l s e {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” Attendendo s t r u t t u r a , o t t e n g o %d\n” , nr ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
}
nr=r e a d ( p f d [ 0 ] , & ch , 1 ) ; i f ( nr==0) {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
”Ora l a p i p e e ’ c h i u s a \n” ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ;
}
return ( 0 ) ; }
9. (20 minuti) es96.c Una pipe per N processi figli. Far creare al padre N processi (con N valore del primo argomento) ed utilizzare una singola pipe per passare una struttura di dati da ogni figlio al padre.
Soluzione:
/∗ f i l e : e s 9 6 . c
∗ j o b : 1 p i p e , N p r o c e s s i f i g l i
∗/
#include <u n i s t d . h>
#include <s t d i o . h>
#include < s t r i n g . h>
#include < s t d l i b . h>
typedef i n t p i p e t [ 2 ] ; char msg [ 2 5 6 ] ;
p i p e t ∗ p i p e s ; s t r u c t {
Parent
F[0] F[1] F[N−1]
pipes[0]
i n t i n d i c e ; } s t r u t t u r a ;
i n t f i g l i o ( i n t a r g ) ;
i n t main ( i n t a r g c , char ∗∗ a r g v ) { i n t n p i p e ;
i n t n f i g l i ; p i d t p i d ; i n t i ; i n t nr ;
i f ( a r g c <2) { /∗ c o n t r o l l o num a r g s ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” Uso : %s N\n” , a r g v [ 0 ] ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
n f i g l i =a t o i ( a r g v [ 1 ] ) ;
i f ( n f i g l i <=0) { /∗ c o n t r o l l o N ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
”N(%d ) non v a l i d o \n” , n f i g l i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
n p i p e =1;
p i p e s = m a l l o c ( s i z e o f ( p i p e t ) ∗ n p i p e ) ; i f ( p i p e s==NULL) { /∗ c o n t r o l l o m a l l o c ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” A l l o c a z i o n e f a l l i t a \n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
f o r ( i =0; i <n p i p e ; i ++) { /∗ p e r o g n i p i p e ∗/
/∗ c r e o l a c o p p i a d i f d s ∗/
i f ( p i p e ( p i p e s [ i ] ) ! = 0 ) { /∗ e r r o r e ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” p i p e f a l l i t a i n %d\n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
} }
f o r ( i =0; i < n f i g l i ; i ++) { /∗ p e r o g n i f i g l i o ∗/
p i d=f o r k ( ) ; /∗ l o c r e o ∗/
switch ( p i d ) {
case 0 : /∗ o g n i f i g l i o e s e g u e l a f u n z i o n e e t e r m i n a ∗/
return ( f i g l i o ( i ) ) ; case −1:
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” f o r k ( ) f a l l i t a i n %d\n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
}
/∗ s o l o i l p a d r e a r r i v a q u i ∗/
c l o s e ( p i p e s [ 0 ] [ 1 ] ) ; /∗ i l p a d r e non s c r i v e , c h i u d o i l f d d i s c r i t t ∗/
f o r ( i =0; i < n f i g l i ; i ++) { /∗ p e r o g n i f i g l i o ∗/
nr=r e a d ( p i p e s [ 0 ] [ 0 ] , & s t r u t t u r a , s i z e o f ( s t r u t t u r a ) ) ; /∗ N e l l a p i p e vengono i n s e r i t e d a i f i g l i d e i ” b l o c c h i ”
∗ d i b y t e l a c u i d i m e n s i o n e e ’ p a r i a q u e l l a d e l t i p o
∗ ” s t r u t t u r a ” . V i s t o che l ’ o p e r a z i o n e d i w r i t e e ’
∗ atomica , i l p a d r e o l e g g e una i n t e r a s t r u t t u r a o
∗ s i s o s p e n d e f i n o a l momento d e l l a d i s p o n i b i l i t a ’
∗ o , ancora , o t t i e n e 0 p e r i n d i c a r e che l a p i p e
∗ non ha d a t i e non ne p o t r a ’ mai p i u ’ a v e r e , o v v e r o
∗ quando t u t t i i p r o c e s s i che avevano i l f i l e d e s c r i p t o r
∗ d e l l a t o d i s c r i t t u r a l o hanno c h i u s o . ∗/
switch ( nr ) {
case 0 : /∗ p i p e c h i u s a , t u t t i i f i g l i sono t e r m i n a t i ma q u a l c u n o non ha i n v i a t o l a s t r u t t u r a ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” R i c e v o s o l o %d s t r u t t u r e \n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ;
case s i z e o f ( s t r u t t u r a ) : /∗ l e t t u r a d i una s t r u c t ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” R i c e v o l a s t r u t t u r a :%d\n” , s t r u t t u r a . i n d i c e ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ;
break ;
d e f a u l t : /∗ e r r o r e ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” R i c e v o s o l o %d b y t e \n” , nr ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
}
return ( 0 ) ; }
/∗ f u n z i o n e f i g l i o ∗/
i n t f i g l i o ( i n t a r g ) { i n t nw ;
c l o s e ( p i p e s [ 0 ] [ 0 ] ) ; /∗ f i g l i o non l e g g e ∗/
s t r u t t u r a . i n d i c e=a r g ;
nw=w r i t e ( p i p e s [ 0 ] [ 1 ] , & s t r u t t u r a , s i z e o f ( s t r u t t u r a ) ) ; i f (nw!= s i z e o f ( s t r u t t u r a ) ) {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” F i g l i o con i n d i c e %d s c r i v e s o l o %d b y t e s \n” , arg , nw ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
return ( 0 ) ; }
10. (20 minuti) es97.c N pipe per N processi figli. Far creare al padre N processi ed utilizzare una pipe per ogni processo figlio. Leggere le strutture in modo ordinato, prima dall’ultimo figlio poi dal penultimo e cos`ı via fino al primo.
Soluzione:
Parent
F[0] F[1] F[N−1]
pipes[0]
pipes[1]
pipes[N−1]
/∗ f i l e : e s 9 7 . c
∗ j o b : N p i p e , N p r o c e s s i f i g l i
∗/
#include <u n i s t d . h>
#include <s t d i o . h>
#include < s t r i n g . h>
#include < s t d l i b . h>
typedef i n t p i p e t [ 2 ] ; char msg [ 2 5 6 ] ;
p i p e t ∗ p i p e s ; s t r u c t {
i n t i n d i c e ; } s t r u t t u r a ;
i n t f i g l i o ( i n t a r g ) ;
i n t main ( i n t a r g c , char ∗∗ a r g v ) { i n t n p i p e ;
i n t n f i g l i ; p i d t p i d ; i n t i , j ; i n t nr ;
i f ( a r g c <2) { /∗ c o n t r o l l o num a r g s ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” Uso : %s N\n” , a r g v [ 0 ] ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
n f i g l i =a t o i ( a r g v [ 1 ] ) ;
i f ( n f i g l i <=0) { /∗ c o n t r o l l o N ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
”N(%d ) non v a l i d o \n” , n f i g l i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
n p i p e= n f i g l i ;
p i p e s = m a l l o c ( s i z e o f ( p i p e t ) ∗ n p i p e ) ; i f ( p i p e s==NULL) { /∗ c o n t r o l l o m a l l o c ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” A l l o c a z i o n e f a l l i t a \n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
f o r ( i =0; i <n p i p e ; i ++) { /∗ p e r o g n i p i p e ∗/
/∗ c r e o l a c o p p i a d i f d s ∗/
i f ( p i p e ( p i p e s [ i ] ) ! = 0 ) { /∗ e r r o r e ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” p i p e f a l l i t a i n %d\n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
} }
f o r ( i =0; i < n f i g l i ; i ++) { /∗ p e r o g n i f i g l i o ∗/
p i d=f o r k ( ) ; /∗ l o c r e o ∗/
switch ( p i d ) {
case 0 : /∗ o g n i f i g l i o e s e g u e l a f u n z i o n e
e t e r m i n a . Prima d e l l a c h i a m a t a c h i u d o i f d c h e i l f i g l i o non d e v e u s a r e ∗/
f o r ( j =0; j <n p i p e ; j ++) {
c l o s e ( p i p e s [ j ] [ 0 ] ) ; /∗ f i g l i o non l e g g e ∗/
i f ( j != i ) {
/∗ f i g l i o non s c r i v e s u l l e a l t r e ∗/
c l o s e ( p i p e s [ j ] [ 1 ] ) ; }
}
return ( f i g l i o ( i ) ) ; case −1:
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” f o r k ( ) f a l l i t a i n %d\n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
}
/∗ s o l o i l p a d r e a r r i v a q u i ∗/
f o r ( i =0; i <n p i p e ; i ++) { /∗ p e r t u t t e l e p i p e ∗/
c l o s e ( p i p e s [ i ] [ 1 ] ) ; /∗ i l p a d r e non s c r i v e , c h i u d o i l f d d i s c r i t t ∗/
}
f o r ( i=npipe −1; i >=0; i −−) { /∗ p e r o g n i p i p e , d a l l ’ u l t i m a a l l a prima ∗/
nr=r e a d ( p i p e s [ i ] [ 0 ] , & s t r u t t u r a , s i z e o f ( s t r u t t u r a ) ) ; /∗ N e l l a p i p e vengono i n s e r i t e d a i f i g l i d e i ” b l o c c h i ”
∗ d i b y t e l a c u i d i m e n s i o n e e ’ p a r i a q u e l l a d e l t i p o
∗ ” s t r u t t u r a ” . V i s t o che l ’ o p e r a z i o n e d i w r i t e e ’
∗ atomica , i l p a d r e o l e g g e una i n t e r a s t r u t t u r a o
∗ s i s o s p e n d e f i n o a l momento d e l l a d i s p o n i b i l i t a ’
∗ o , ancora , o t t i e n e 0 p e r i n d i c a r e che l a p i p e
∗ non ha d a t i e non ne p o t r a ’ mai p i u ’ a v e r e , o v v e r o
∗ quando t u t t i i p r o c e s s i che avevano i l f i l e d e s c r i p t o r
∗ d e l l a t o d i s c r i t t u r a l o hanno c h i u s o . ∗/
switch ( nr ) {
case 0 : /∗ p i p e c h i u s a , t u t t i i f i g l i sono t e r m i n a t i ma q u a l c u n o non ha i n v i a t o l a s t r u t t u r a ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” R i c e v o s o l o %d s t r u t t u r e \n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ;
case s i z e o f ( s t r u t t u r a ) : /∗ l e t t u r a d i una s t r u c t ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” R i c e v o l a s t r u t t u r a :%d\n” , s t r u t t u r a . i n d i c e ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ;
break ;
d e f a u l t : /∗ e r r o r e ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” R i c e v o s o l o %d b y t e \n” , nr ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
}
return ( 0 ) ; }
/∗ f u n z i o n e f i g l i o ∗/
i n t f i g l i o ( i n t a r g ) { i n t nw ;
s t r u t t u r a . i n d i c e=a r g ;
nw=w r i t e ( p i p e s [ a r g ] [ 1 ] , & s t r u t t u r a , s i z e o f ( s t r u t t u r a ) ) ; i f (nw!= s i z e o f ( s t r u t t u r a ) ) {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” F i g l i o con i n d i c e %d s c r i v e s o l o %d b y t e s \n” , arg , nw ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
return ( 0 ) ; }
11. (20 minuti) es98.c N pipe per N processi figli. Far creare al padre N processi ed utilizzare una pipe per ogni processo figlio ma diretta dal padre verso il figlio. Ogni figlio attende un carattere poi stampa il proprio pid su stdout. Il padre manda un carattere ad ogni figlio dall’ultimo al primo.
Soluzione:
/∗ f i l e : e s 9 8 . c
∗ j o b : N p i p e , N p r o c e s s i f i g l i , da p a d r e a f i g l i o
∗/
#include <u n i s t d . h>
#include <s y s / t y p e s . h>
#include <s t d i o . h>
#include < s t r i n g . h>
#include < s t d l i b . h>
Parent
F[0] F[1] F[N−1]
pipes[0]
pipes[1]
pipes[N−1]
typedef i n t p i p e t [ 2 ] ; char msg [ 2 5 6 ] ;
char ch ;
p i p e t ∗ p i p e s ;
i n t f i g l i o ( i n t a r g ) ;
i n t main ( i n t a r g c , char ∗∗ a r g v ) { i n t n p i p e ;
i n t n f i g l i ; p i d t p i d ; i n t i , j ; i n t nw ;
i f ( a r g c <2) { /∗ c o n t r o l l o num a r g s ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” Uso : %s N\n” , a r g v [ 0 ] ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
n f i g l i =a t o i ( a r g v [ 1 ] ) ;
i f ( n f i g l i <=0) { /∗ c o n t r o l l o N ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
”N(%d ) non v a l i d o \n” , n f i g l i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
n p i p e= n f i g l i ;
p i p e s = m a l l o c ( s i z e o f ( p i p e t ) ∗ n p i p e ) ; i f ( p i p e s==NULL) { /∗ c o n t r o l l o m a l l o c ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” A l l o c a z i o n e f a l l i t a \n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
f o r ( i =0; i <n p i p e ; i ++) { /∗ p e r o g n i p i p e ∗/
/∗ c r e o l a c o p p i a d i f d s ∗/
i f ( p i p e ( p i p e s [ i ] ) ! = 0 ) { /∗ e r r o r e ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” p i p e f a l l i t a i n %d\n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
} }
f o r ( i =0; i < n f i g l i ; i ++) { /∗ p e r o g n i f i g l i o ∗/
p i d=f o r k ( ) ; /∗ l o c r e o ∗/
switch ( p i d ) {
case 0 : /∗ o g n i f i g l i o e s e g u e l a f u n z i o n e
e t e r m i n a . Prima d e l l a c h i a m a t a c h i u d o i f d c h e i l f i g l i o non d e v e u s a r e ∗/
f o r ( j =0; j <n p i p e ; j ++) {
c l o s e ( p i p e s [ j ] [ 1 ] ) ; /∗ f i g l i o non s c r i v e ∗/
i f ( j != i ) {
/∗ f i g l i o non l e g g e d a l l e a l t r e ∗/
c l o s e ( p i p e s [ j ] [ 0 ] ) ; }
}
return ( f i g l i o ( i ) ) ; case −1:
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” f o r k ( ) f a l l i t a i n %d\n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
}
/∗ s o l o i l p a d r e a r r i v a q u i ∗/
f o r ( i =0; i <n p i p e ; i ++) { /∗ p e r t u t t e l e p i p e ∗/
c l o s e ( p i p e s [ i ] [ 0 ] ) ; /∗ i l p a d r e non l e g g e , c h i u d o i l f d d i l e t t ∗/
}
f o r ( i=npipe −1; i >=0; i −−) { /∗ p e r o g n i p i p e , d a l l ’ u l t i m a a l l a prima ∗/
nw=w r i t e ( p i p e s [ i ] [ 1 ] , & ch , 1 ) ; switch (nw) {
case 0 : /∗ i m p o s s i b i l e , s e non c ’ e ’ s p a z i o a t t e n d e ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
”Non s c r i v o i l c a r a t t e r e \n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; case 1 : /∗ OK ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
”Do i l v i a a l f i g l i o %d\n” , i ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ;
break ;
d e f a u l t : /∗ e r r o r e ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” E r r o r e i n w r i t e \n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
} }
return ( 0 ) ; }
/∗ f u n z i o n e f i g l i o ∗/
i n t f i g l i o ( i n t a r g ) { i n t nr ;
nr=r e a d ( p i p e s [ a r g ] [ 0 ] , & ch , 1 ) ; i f ( nr ! = 1 ) {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” F i g l i o con i n d i c e %d o t t i e n e %d da r e a d \n” , arg , nr ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
/∗ s e q u i , ho r i c e v u t o l ’ ok e stampo i l mio p i d ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) , ” F i g l i o con p i d %d\n” , g e t p i d ( ) ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ;
return ( 0 ) ; }
/∗ A t t e n z i o n e : q u e s t o s i s t e m a non a s s i c u r a c h e l e w r i t e d e i f i g l i su s t d o u t a v v e n g a n o i n s e q u e n z a ! Una v o l t a o t t e n u t o l ’ ok d a l p a d r e i f i g l i d i v e n t a n o p r o c e s s i ” e s e g u i b i l i ” e l ’ o r d i n e con i l q u a l e i l s i s t e m a a s s e g n a l e s l i c e a i f i g l i e ’ c a s u a l e . Una s o l u z i o n e e s a t t a d e l p r o b l e m a s i o t t i e n e con i l p r o s s i m o s o r g e n t e ∗/
12. (20 minuti) es99.c N pipe per N+1 processi figli. Far creare al padre N processi ed utilizzare una pipe per collegare ogni processo figlio al successivo. Il primo processo figlio emette il proprio pid poi invia un carattere al secondo che, dopo aver stampato il proprio pid, attiva il successivo ...
Soluzione:
Parent
F[0] F[1] F[N−1]
pipes[0] pipes[1] pipes[N−2]
/∗ f i l e : e s 9 9 . c
∗ j o b : N p i p e , N+1 p r o c e s s i f i g l i , da f i g l i o a f i g l i o
∗/
#include <u n i s t d . h>
#include <s y s / t y p e s . h>
#include <s t d i o . h>
#include < s t r i n g . h>
#include < s t d l i b . h>
#include <s y s / w a i t . h>
typedef i n t p i p e t [ 2 ] ; char msg [ 2 5 6 ] ;
char ch ;
p i p e t ∗ p i p e s ;
i n t f i g l i o ( i n t arg , i n t u l t i m o ) ; i n t main ( i n t a r g c , char ∗∗ a r g v ) {
i n t n p i p e ; i n t n f i g l i ; p i d t p i d ;
i n t i , j ;
i f ( a r g c <2) { /∗ c o n t r o l l o num a r g s ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” Uso : %s N\n” , a r g v [ 0 ] ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
n f i g l i =a t o i ( a r g v [ 1 ] ) ;
i f ( n f i g l i <=1) { /∗ c o n t r o l l o N ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
”N(%d ) non v a l i d o \n” , n f i g l i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
n p i p e=n f i g l i −1;
p i p e s = m a l l o c ( s i z e o f ( p i p e t ) ∗ n p i p e ) ; i f ( p i p e s==NULL) { /∗ c o n t r o l l o m a l l o c ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” A l l o c a z i o n e f a l l i t a \n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
f o r ( i =0; i <n p i p e ; i ++) { /∗ p e r o g n i p i p e ∗/
/∗ c r e o l a c o p p i a d i f d s ∗/
i f ( p i p e ( p i p e s [ i ] ) ! = 0 ) { /∗ e r r o r e ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” p i p e f a l l i t a i n %d\n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
} }
f o r ( i =0; i < n f i g l i ; i ++) { /∗ p e r o g n i f i g l i o ∗/
p i d=f o r k ( ) ; /∗ l o c r e o ∗/
switch ( p i d ) {
case 0 : /∗ o g n i f i g l i o e s e g u e l a f u n z i o n e
e t e r m i n a . Prima d e l l a c h i a m a t a c h i u d o i f d c h e i l f i g l i o non d e v e u s a r e ∗/
f o r ( j =0; j <n p i p e ; j ++) {
i f ( j != i ) { /∗ f i g l i o [ i ] s c r i v e su p i p e [ i ] ∗/
c l o s e ( p i p e s [ j ] [ 1 ] ) ; }
i f ( j ! = ( i −1)) { /∗ e l e g g e da p i p e [ i −1] ∗/
c l o s e ( p i p e s [ j ] [ 0 ] ) ; }
}
return ( f i g l i o ( i , n f i g l i − 1 ) ) ; case −1:
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” f o r k ( ) f a l l i t a i n %d\n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
}
/∗ s o l o i l p a d r e a r r i v a q u i ∗/
f o r ( i =0; i <n p i p e ; i ++) { /∗ p e r t u t t e l e p i p e ∗/
c l o s e ( p i p e s [ i ] [ 0 ] ) ; /∗ i l p a d r e non l e g g e , c h i u d o i l f d d i l e t t ∗/
c l o s e ( p i p e s [ i ] [ 1 ] ) ; /∗ e non s c r i v e , c h i u d o i l f d d i s c r i t t u r a ∗/
}
/∗ v o l e n d o , p o s s o a t t e n d e r e i f i g l i p e r r e c u p e r a r e g l i e x i t v a l u e ∗/
f o r ( i =0; i < n f i g l i ; i ++) { w a i t (NULL ) ;
}
return ( 0 ) ; }
/∗ f u n z i o n e f i g l i o ∗/
i n t f i g l i o ( i n t arg , i n t u l t i m o ) { i n t nr , nw ;
i f ( a r g ! = 0 ) { /∗ F [ 0 ] non d e v e a t t e n d e r e ∗/
nr=r e a d ( p i p e s [ arg − 1 ] [ 0 ] , & ch , 1 ) ; /∗ r e a d b l o c c a n t e ∗/
i f ( nr ! = 1 ) {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” F i g l i o con i n d i c e %d o t t i e n e %d da r e a d \n” , arg , nr ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
}
/∗ s e q u i , ho r i c e v u t o l ’ ok e stampo i l mio p i d ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) , ” F i g l i o con p i d %d\n” , g e t p i d ( ) ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ;
/∗ o r a do i l v i a a l f i g l i o s u c c e s s i v o a meno c h e q u e s t o non s i a
∗ l ’ u l t i m o f i g l i o ∗/
i f ( a r g != u l t i m o ) {
nw=w r i t e ( p i p e s [ a r g ] [ 1 ] , & ch , 1 ) ; i f (nw! = 1 ) {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” F i g l i o con i n d i c e %d o t t i e n e %d da w r i t e \n” , arg , nw ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
}
return ( 0 ) ; }
13. (20 minuti) es9A.c N pipe per N+1 processi. Come prima ma il primo processo a stampare il pid `e l’ultimo creato
Soluzione:
/∗ f i l e : es9A . c
∗ j o b : N p i p e , N+1 p r o c e s s i f i g l i , da f i g l i o a f i g l i o i n o r d i n e i n v e r s o
∗/
#include <u n i s t d . h>
#include <s y s / t y p e s . h>
#include <s t d i o . h>
#include < s t r i n g . h>
#include < s t d l i b . h>
#include <s y s / w a i t . h>
typedef i n t p i p e t [ 2 ] ;
Parent
F[0] F[1] F[N−1]
pipes[0] pipes[1] pipes[N−2]
char msg [ 2 5 6 ] ; char ch ;
p i p e t ∗ p i p e s ;
i n t f i g l i o ( i n t arg , i n t u l t i m o ) ; i n t main ( i n t a r g c , char ∗∗ a r g v ) {
i n t n p i p e ; i n t n f i g l i ; p i d t p i d ; i n t i , j ;
i f ( a r g c <2) { /∗ c o n t r o l l o num a r g s ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” Uso : %s N\n” , a r g v [ 0 ] ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
n f i g l i =a t o i ( a r g v [ 1 ] ) ;
i f ( n f i g l i <=1) { /∗ c o n t r o l l o N ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
”N(%d ) non v a l i d o \n” , n f i g l i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
n p i p e=n f i g l i −1;
p i p e s = m a l l o c ( s i z e o f ( p i p e t ) ∗ n p i p e ) ; i f ( p i p e s==NULL) { /∗ c o n t r o l l o m a l l o c ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” A l l o c a z i o n e f a l l i t a \n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
}
f o r ( i =0; i <n p i p e ; i ++) { /∗ p e r o g n i p i p e ∗/
/∗ c r e o l a c o p p i a d i f d s ∗/
i f ( p i p e ( p i p e s [ i ] ) ! = 0 ) { /∗ e r r o r e ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” p i p e f a l l i t a i n %d\n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;
} }
f o r ( i =0; i < n f i g l i ; i ++) { /∗ p e r o g n i f i g l i o ∗/
p i d=f o r k ( ) ; /∗ l o c r e o ∗/
switch ( p i d ) {
case 0 : /∗ o g n i f i g l i o e s e g u e l a f u n z i o n e
e t e r m i n a . Prima d e l l a c h i a m a t a c h i u d o i f d c h e i l f i g l i o non d e v e u s a r e ∗/
f o r ( j =0; j <n p i p e ; j ++) {
i f ( j ! = ( i −1)) { /∗ f i g l i o [ i ] s c r i v e su p i p e [ i −1] ∗/
c l o s e ( p i p e s [ j ] [ 1 ] ) ; }
i f ( j != i ) { /∗ e l e g g e da p i p e [ i ] ∗/
c l o s e ( p i p e s [ j ] [ 0 ] ) ; }
}
return ( f i g l i o ( i , n f i g l i − 1 ) ) ; case −1:
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” f o r k ( ) f a l l i t a i n %d\n” , i ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
}
/∗ s o l o i l p a d r e a r r i v a q u i ∗/
f o r ( i =0; i <n p i p e ; i ++) { /∗ p e r t u t t e l e p i p e ∗/
c l o s e ( p i p e s [ i ] [ 0 ] ) ; /∗ i l p a d r e non l e g g e , c h i u d o i l f d d i l e t t ∗/
c l o s e ( p i p e s [ i ] [ 1 ] ) ; /∗ e non s c r i v e , c h i u d o i l f d d i s c r i t t u r a ∗/
}
/∗ v o l e n d o , p o s s o a t t e n d e r e i f i g l i p e r r e c u p e r a r e g l i e x i t v a l u e ∗/
f o r ( i =0; i < n f i g l i ; i ++) { w a i t (NULL ) ;
}
return ( 0 ) ; }
/∗ f u n z i o n e f i g l i o ∗/
i n t f i g l i o ( i n t arg , i n t u l t i m o ) { i n t nr , nw ;
i f ( a r g != u l t i m o ) { /∗ F [ N−1] non d e v e a t t e n d e r e ∗/
nr=r e a d ( p i p e s [ a r g ] [ 0 ] , & ch , 1 ) ; /∗ r e a d b l o c c a n t e ∗/
i f ( nr ! = 1 ) {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” F i g l i o con i n d i c e %d o t t i e n e %d da r e a d \n” , arg , nr ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
}
/∗ s e q u i , ho r i c e v u t o l ’ ok e stampo i l mio p i d ∗/
s n p r i n t f ( msg , s i z e o f ( msg ) , ” F i g l i o con p i d %d\n” , g e t p i d ( ) ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ;
/∗ o r a do i l v i a a l f i g l i o s u c c e s s i v o a meno c h e q u e s t o non s i a
∗ i l primo f i g l i o ∗/
i f ( a r g ! = 0 ) {
nw=w r i t e ( p i p e s [ arg − 1 ] [ 1 ] , & ch , 1 ) ; i f (nw! = 1 ) {
s n p r i n t f ( msg , s i z e o f ( msg ) ,
” F i g l i o con i n d i c e %d o t t i e n e %d da w r i t e \n” , arg , nw ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ;
return ( 1 ) ; }
}
return ( 0 ) ; }