• Non ci sono risultati.

Lab. di Sistemi Operativi Esercitazioni proposte per la lezione del 13 maggio 2011

N/A
N/A
Protected

Academic year: 2021

Condividi "Lab. di Sistemi Operativi Esercitazioni proposte per la lezione del 13 maggio 2011"

Copied!
22
0
0

Testo completo

(1)

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

(2)

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 ) ) ; }

}

(3)

/∗ 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).

(4)

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

(5)

∗ 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

(6)

∗ 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

(7)

∗/

#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

(8)

∗ 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 ) ,

(9)

” 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 {

(10)

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 ) ;

} }

(11)

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 ) ) {

(12)

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 ) ;

}

(13)

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 ’

(14)

∗ 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>

(15)

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 ) ;

(16)

} }

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 ) {

(17)

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 ;

(18)

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 ∗/

(19)

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 ] ;

(20)

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 ) ;

} }

(21)

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 ) {

(22)

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 ) ; }

Riferimenti

Documenti correlati

(15 minuti) es62p.sh Controllo parametri della parte shell del compito del 6 febbraio 2009 : La parte in Shell deve prevedere tre parametri: il primo deve essere il nome assoluto di

, FN e riportare su stdout un carattere di ogni file indicato, il primo carattere del primo file F1, l’ultimo carat- tere dell’ultimo file FN, il secondo carattere del secondo file

(15 minuti) es88.c Recupero degli exit value dei processi figli: modificare es88.c in modo che il processo padre attenda la terminazione di tutti i processi figli riportando su

Ognuno di tali processi figli deve creare un file il cui nome (FiK) risulti dalla concatenazione del nome del file associato (Fi) con la stringa che corrisponde al numero K;

Determinare con un programma c (es111.c) il segnale che causa la terminazione di un processo figlio quando questo tenta di scrivere su una pipe con lato di lettura chiuso

(10 minuti) es55p.sh Controllo parametri della parte shell del compito del 6 febbraio 2009 : La parte in Shell deve prevedere tre parametri: il primo deve essere il nome assoluto di

Il processo Pi deve cominciare a leggere cercando la prima occorrenza del carattere C; appena trovata deve comunicare all’altro processo della coppia P2*N-1-i la posizione

anche per l’irrazionalità delle conseguenze di una deroga relativa solo alla prole di età inferiore ai dieci anni, sembra doversi concludere che i casi in cui può