• Non ci sono risultati.

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

N/A
N/A
Protected

Academic year: 2021

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

Copied!
19
0
0

Testo completo

(1)

Lab. di Sistemi Operativi

Esercitazioni proposte per la lezione del 20 maggio 2011

Utilizzando il compilatore gcc in Linux e disponendosi in gruppi di due persone per ogni PC del labora- torio.

1. (45 minuti) es101.c Soluzione al compito del 8 aprile 2005

La parte in C accetta un numero variabile di parametri che rappresentano nomi di file F1...FM e un numero K strettamente positivo, pari e strettamente minore di 7 che rappresenta il numero di linee di ogni file. Il processo padre deve generare M processi figli (P1..PM): ogni processo figlio associato ad uno dei file Fi. 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; quindi, ogni figlio deve creare un processo nipote: la coppia figlio e nipote esegue concorrentemente leggendo, rispettivamente, il figlio le linee dispari e il nipote le linee pari. Il processo nipote, dopo la lettura di ogni linea pari, calcola la sua lunghezza (LP) e la comunica al processo figlio; il processo figlio, dopo la lettura di ogni linea dispari, calcola la sua lunghezza (LD) e riceve dal nipote LP: se LD minore di LP, allora il processo figlio scrive la sua linea sul file FiK(*) . Ogni processo figlio deve ritornare al padre il numero di linee scritte sul file FiK.

Il padre, dopo che i figli sono terminati, deve stampare su standard output i PID di ogni figlio con il corrispondente valore ritornato.

(*) Le letture dal singolo file da parte di una coppia di processi figlio-nipote non devono essere sin- cronizzate.

2. (45 minuti) es102.c Soluzione al compito del 12 marzo 2004

La parte in C accetta un numero variabile di parametri che rappresentano un nome di file F e N caratteri C1 ... CN. Il processo padre deve generare N processi figli (P1..PN): ogni processo figlio

`

e associato ad uno dei caratteri Ci. Ognuno di tali processi figli esegue concorrentemente e verifica se il file F contiene il carattere associato Ci; in particolare, ogni processo figlio deve riportare sullo standard output il numero d’ordine di ogni linea di F che contiene il carattere associato. La scrittura dei processi figli deve essere sincronizzata (senza l’intervento del padre) affinch´e venga stampata prima una informazione di P1, poi di P2, e cos via fino a PN, dopodich´e si ricomincia da P1 finch´e tutti i processi non hanno verificato tutto il file. Al termine, ogni processo figlio deve ritornare al padre il numero di linee che contengono il carattere associato. Il padre visualizza su standard output i valori ritornati dai figli.

NOTA BENE:

Si consideri ipotizzabile che i processi figli terminano in cascata, dal primo all’ultimo.

3. Invertire l’ordine di sincronizzazione dei figli nell’esercizio es102.c (es103.c)

4. Creiamo un sorgente C es104.c che possa servire come base di partenza per la realizzazione di appli- cazioni concorrenti.

5. Creiamo un Makefile per la compilazione dell’esempio

(2)

Soluzione

Esercitazioni proposte per la lezione del 20 maggio 2011

Utilizzando il compilatore gcc in Linux e disponendosi in gruppi di due persone per ogni PC del labora- torio.

1. (45 minuti) es101.c Soluzione al compito del 8 aprile 2005

La parte in C accetta un numero variabile di parametri che rappresentano nomi di file F1...FM e un numero K strettamente positivo, pari e strettamente minore di 7 che rappresenta il numero di linee di ogni file. Il processo padre deve generare M processi figli (P1..PM): ogni processo figlio associato ad uno dei file Fi. 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; quindi, ogni figlio deve creare un processo nipote: la coppia figlio e nipote esegue concorrentemente leggendo, rispettivamente, il figlio le linee dispari e il nipote le linee pari. Il processo nipote, dopo la lettura di ogni linea pari, calcola la sua lunghezza (LP) e la comunica al processo figlio; il processo figlio, dopo la lettura di ogni linea dispari, calcola la sua lunghezza (LD) e riceve dal nipote LP: se LD minore di LP, allora il processo figlio scrive la sua linea sul file FiK(*) . Ogni processo figlio deve ritornare al padre il numero di linee scritte sul file FiK.

Il padre, dopo che i figli sono terminati, deve stampare su standard output i PID di ogni figlio con il corrispondente valore ritornato.

(*) Le letture dal singolo file da parte di una coppia di processi figlio-nipote non devono essere sin- cronizzate.

Soluzione:

Parent

pfn pfn

F[0] F[1]

N[0] N[1] N[M−1]

pfn

F[M−1]

wait()

wait() wait()

/∗ f i l e : e s 1 0 1 . c

∗ j o b : s o l u z i o n e 8 a p r i l e 2005

∗/

#include <s t d i o . h>

#include < s t d l i b . h>

(3)

#include <u n i s t d . h>

#include <s y s / w a i t . h>

#include < f c n t l . h>

#include <s t d a r g . h>

i n t M; /∗ numero d i p r o c e s s i f i g l i ∗/

i n t K; /∗ u l t i m o argomento ∗/

p i d t p i d ; /∗ a p p o g g i o p e r v a l o r e p i d ∗/

i n t s t a t u s ; /∗ a p p o g g i o p e r w a i t ∗/

i n t p f n [ 2 ] ; /∗ p i p e f i g l i o −n i p o t e , a t t e n z i o n e o g n i p r o c e s s o f i g l i o ha l a sua i s t a n z a d i q u e s t a v a r i a b i l e q u i n d i l e p i p e c r e a t e sono ”M” ∗/

i n t f d r , fdw ; /∗ f i l e d e s c r i p t o r s p e r r e a d e w r i t e ∗/

i n t i n d i c e ; /∗ i n d i c e su l i n e a ∗/

char l i n e a [ 2 5 6 ] ; /∗ b u f f e r d i l i n e a ∗/

char FiK [ 8 0 ] ; /∗ nome f i l e d i u s c i t a ∗/

i n t LP , LD ; /∗ l u n g h e z z e l i n e a ∗/

i n t l i n e a c o r r ; /∗ l i n e a c o r r e n t e ∗/

i n t n o n s c r i t t e ; /∗ numero d i l i n e e non s c r i t t e ∗/

/∗ a b b i n a m e n t o s n p r i n t f+w r i t e ∗/

void z p r i n t f ( i n t fd , const char ∗ fmt , . . . ) ; /∗ f u n z i o n e f i g l i o ∗/

i n t f i g l i o ( char ∗ f i l e n a m e , i n t i ) ; /∗ f u n z i o n e n i p o t e ∗/

i n t n i p o t e ( char ∗ f i l e n a m e , i n t i ) ; i n t main ( i n t a r g c , char ∗∗ a r g v ) {

i n t i ; /∗ i n t d i a p p o g g i o ∗/

/∗ c o n t r o l l o numero d i a r g o m e n t i ∗/

i f ( a r g c <3) {

z p r i n t f ( 2 , ” E r r o r e n e l numero d i a r g o m e n t i \n” ) ; return ( 1 ) ;

}

M=a r g c −2; /∗ numero d i p r o c e s s i f i g l i ∗/

K=a t o i ( a r g v [ a r g c − 1 ] ) ; /∗ numero K, u l t i m o argomento ∗/

i f ( (K< = 0 ) | | (K> = 7 ) | | ( (K%2)!=0)) {

z p r i n t f ( 2 , ” Parametro K non v a l i d o : %d\n” ,K ) ; return ( 2 ) ;

}

/∗ c r e a z i o n e f i g l i e a t t r i b u z i o n e a r g o m e n t i ∗/

f o r ( i =0; i <M; i ++) { switch ( f o r k ( ) ) {

case 0 : /∗ f i g l i o ∗/

return ( f i g l i o ( a r g v [ i + 1 ] , i ) ) ; case −1:

/∗ e r r o r e ∗/

z p r i n t f ( 2 , ” E r r o r e n e l l a %d f o r k \n” , i ) ; return ( 3 ) ;

} }

/∗ r e c u p e r o e x i t s t a t u s d e i f i g l i ( non d e i n i p o t i ) ∗/

f o r ( i =0; i <M; i ++) { p i d=w a i t (& s t a t u s ) ;

i f (WIFEXITED( s t a t u s ) ) { z p r i n t f ( 1 ,

” 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 a t u s ) ) ;

(4)

} e l s e {

z p r i n t f ( 1 ,

” I l f i g l i o con p i d %d e ’ t e r m i n a t o p e r i l s e g n a l e %d\n” , pid , WTERMSIG( s t a t u s ) ) ;

} }

return ( 0 ) ; }

void z p r i n t f ( i n t fd , const char ∗ fmt , . . . ) { /∗ p r i n t f wrapper u s i n g w r i t e i n s t e a d ∗/

s t a t i c char msg [ 2 5 6 ] ; v a l i s t ap ;

i n t n ;

v a s t a r t ( ap , fmt ) ;

n=v s n p r i n t f ( msg , 2 5 6 , fmt , ap ) ; w r i t e ( fd , msg , n ) ;

v a e n d ( ap ) ; }

i n t f i g l i o ( char ∗ f i l e n a m e , i n t i ) { char ch ;

/∗ c r e o l a p i p e f i g l i o −n i p o t e ∗/

i f ( p i p e ( p f n ) ! = 0 ) {

z p r i n t f ( 2 , ” E r r o r e c r e a z i o n e p i p e f i g l i o −n i p o t e %d\n” , i ) ; a b o r t ( ) ; /∗ t e r m i n o p e r SIGABRT, i l p a d r e s e ne a c c o r g e ∗/

return ( 4 ) ; }

/∗ c r e o i l n i p o t e ∗/

switch ( f o r k ( ) ) { case 0 :

return ( n i p o t e ( f i l e n a m e , i ) ) ; case −1:

/∗ e r r o r e ∗/

z p r i n t f ( 2 , ” E r r o r e n e l l a %d f o r k ( n i p o t e ) \ n” , i ) ; a b o r t ( ) ;

}

c l o s e ( p f n [ 1 ] ) ; /∗ non s c r i v o mai ∗/

/∗ l e g g e l e l i n e e 1 , 3 , . . . e v i t a n d o q u e l l e p a r i ∗/

f d r=open ( f i l e n a m e ,O RDONLY ) ; i f ( f d r <0) {

z p r i n t f ( 2 , ” I m p o s s i b i l e a p r i r e %s \n” , f i l e n a m e ) ; a b o r t ( ) ;

}

s n p r i n t f ( FiK , s i z e o f ( FiK ) , ”%s%d” , f i l e n a m e ,K) ;

#i f d e f DEBUG

z p r i n t f ( 1 , ” C r e a t o %s \n” , FiK ) ;

#endif

fdw=open ( FiK ,O WRONLY| O CREAT | O EXCL, 0 6 6 6 ) ; i f ( fdw <0) {

z p r i n t f ( 2 , ” I m p o s s i b i l e a p r i r e %s \n” , FiK ) ; a b o r t ( ) ;

}

l i n e a c o r r =1;

i n d i c e =0;

f o r ( ; ; ) {

(5)

i f ( r e a d ( f d r ,& ch , 1 ) ! = 1 ) { return ( n o n s c r i t t e ) ; }

#i f d e f DEBUG1

z p r i n t f ( 1 , ” Char %d\n” , ch ) ;

#endif

i f ( ch== ’ \n ’ ) { /∗ f i n e l i n e a ∗/

i f ( ( l i n e a c o r r %2)==1) { LD=i n d i c e ;

/∗ a t t e n d o i n f o da n i p o t e ∗/

#i f d e f DEBUG

z p r i n t f ( 1 , ” Attendo i n f o p e r l i n e a %d l u n g %d\n” , l i n e a c o r r , LD ) ;

#endif

i f ( r e a d ( p f n [ 0 ] , & LP , s i z e o f (LP) ) ! = s i z e o f (LP ) ) { z p r i n t f ( 2 , ” E r r o r e l e t t u r a p i p e \n” ) ;

a b o r t ( ) ; }

i f (LD>LP) {

w r i t e ( fdw , l i n e a , LD ) ;

w r i t e ( fdw , ” \n” , 1 ) ; /∗ f i n e l i n e a ∗/

} e l s e {

n o n s c r i t t e ++;

} }

i n d i c e =0;

l i n e a c o r r ++;

} e l s e i f ( ( l i n e a c o r r %2)==1) { /∗ l i n e a d i s p a r i , memorizzo ∗/

i f ( i n d i c e <s i z e o f ( l i n e a ) ) { l i n e a [ i n d i c e ++]=ch ; }

} }

/∗ f i n e f i g l i o , mai q u i ∗/

a b o r t ( ) ; return ( 0 ) ; }

i n t n i p o t e ( char ∗ f i l e n a m e , i n t i ) { char ch ;

/∗ n i p o t e , l i n e e p a r i ∗/

f d r=open ( f i l e n a m e ,O RDONLY ) ; i f ( f d r <0) {

z p r i n t f ( 2 , ” I m p o s s i b i l e a p r i r e %s \n” , f i l e n a m e ) ; return ( 1 ) ; /∗ r e c u p e r a b i l e con w a i t d a l f i g l i o ∗/

}

l i n e a c o r r =1;

i n d i c e =0;

f o r ( ; ; ) {

i f ( r e a d ( f d r ,& ch , 1 ) ! = 1 ) { /∗ f i n e f i l e ∗/

return ( 0 ) ; }

(6)

i f ( ch== ’ \n ’ ) { /∗ f i n e l i n e a ∗/

i f ( ( l i n e a c o r r %2)==0) { LP=i n d i c e ;

w r i t e ( p f n [ 1 ] , & LP , s i z e o f (LP ) ) ;

#i f d e f DEBUG

z p r i n t f ( 1 , ” I n v i a t a l u n g l i n e a %d , p a r i a %d\n” , l i n e a c o r r , LP ) ;

#endif

}

i n d i c e =0;

l i n e a c o r r ++;

} e l s e { i n d i c e ++;

} }

return ( 0 ) ; }

2. (45 minuti) es102.c Soluzione al compito del 12 marzo 2004

La parte in C accetta un numero variabile di parametri che rappresentano un nome di file F e N caratteri C1 ... CN. Il processo padre deve generare N processi figli (P1..PN): ogni processo figlio

`

e associato ad uno dei caratteri Ci. Ognuno di tali processi figli esegue concorrentemente e verifica se il file F contiene il carattere associato Ci; in particolare, ogni processo figlio deve riportare sullo standard output il numero d’ordine di ogni linea di F che contiene il carattere associato. La scrittura dei processi figli deve essere sincronizzata (senza l’intervento del padre) affinch´e venga stampata prima una informazione di P1, poi di P2, e cos via fino a PN, dopodich´e si ricomincia da P1 finch´e tutti i processi non hanno verificato tutto il file. Al termine, ogni processo figlio deve ritornare al padre il numero di linee che contengono il carattere associato. Il padre visualizza su standard output i valori ritornati dai figli.

NOTA BENE:

Si consideri ipotizzabile che i processi figli terminano in cascata, dal primo all’ultimo.

Soluzione:

/∗ f i l e : e s 1 0 2 . c

∗ j o b : s o l u z i o n e 12 marzo 2004

∗/

#include <s t d i o . h>

#include < s t d l i b . h>

#include <u n i s t d . h>

#include <s y s / t y p e s . h>

#include <s y s / w a i t . h>

#include <s y s / s t a t . h>

#include < f c n t l . h>

#include <s t d a r g . h>

typedef i n t p i p e t [ 2 ] ; /∗ t i p o p e r p i p e ∗/

#define SCRIT 1

#define LETT 0

char ∗F ; /∗ Nome d e l f i l e , v a r i a b i l e g l o b a l e ∗/

i n t N; /∗ Numero d i c a r a t t e r i ∗/

char ∗C ; /∗ E l e n c o d e i c a r a t t e r i , a l l o c a z i o n e d i n a m i c a ∗/

(7)

F[0] F[1] F[N−1]

pipes[N−1]

pipes[1] pipes[2]

pipes[0]

F[1] F[N−1]

F[1]

Parent

pipes[N−1]

pipes[2]

pipes[0]

pipes[2]

N wait()

i n t Npipe ; /∗ Numero d i p i p e da c r e a r e ∗/

p i p e t ∗ P f d s ; /∗ Array d i p i p e , a l l o c a z i o n e d i n a m i c a ∗/

i n t N f i g l i ; /∗ Numero d i f i g l i da f o r k a r e ∗/

i n t ∗ P i d s ; /∗ Array d i p i d , a l l o c a z i o n e d i n a m i c a ∗/

/∗ a b b i n a m e n t o s n p r i n t f+w r i t e ∗/

void z p r i n t f ( i n t fd , const char ∗ fmt , . . . ) ; /∗ 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 ) ;

char ok= ’Q ’ ; /∗ c a r a t t e r e ( c a s u a l e ) c h e i n v i a m o s u l l a p i p e p e r l a s i n c r o n i z z a z i o n e ∗/

i n t main ( i n t a r g c , char ∗∗ argv , char ∗∗ envp ) { i n t i , j ; /∗ q u a l c h e c o n t a t o r e ∗/

/∗ D e t e r m i n a z i o n e d e i d a t i d a l l a command l i n e ∗/

switch ( a r g c ) { case 0 : case 1 : case 2 :

z p r i n t f ( 2 , ” I n s e r i r e i l nome d i f i l e ed almeno un c a r a t t e r e \n” ) ; return ( 1 ) ;

}

F = a r g v [ 1 ] ;

N = a r g c −2; /∗ a r g c v a l e 1 s e non c i sono a r g o m e n t i ∗/

C = m a l l o c (N∗ s i z e o f ( char ) ) ; i f (C==NULL) {

z p r i n t f ( 2 , ” I m p o s s i b i l e a l l o c a r e C\n” ) ; return ( 1 ) ;

(8)

}

f o r ( i =0; i <N; i ++) {

C [ i ]= a r g v [ i + 2 ] [ 0 ] ; /∗ p r e n d o i l primo c a r a t t e r e d e l l a s t r i n g a a r g v [ i +2] ∗/

}

#i f d e f DEBUG

z p r i n t f ( 1 , ”Nome d e l f i l e : %s \n” ,F ) ; z p r i n t f ( 1 , ”Numero d i c a r a t t e r i %d\n” ,N ) ; f o r ( i =0; i <N; i ++) {

z p r i n t f ( 1 , ” C a r a t t e r e d i i n d i c e %d = %c \n” , i , C [ i ] ) ; }

#endif

/∗ P r e d i s p o s i z i o n e d e l s i s t e m a d i s i n c r o n i z z a z i o n e

∗ f r a i p r o c e s s i f i g l i : s i u t i l i z z a una p i p e p e r

∗ c o l l e g a r e o g n i f i g l i o a l s u c c e s s i v o ; l a s i n c r o n i z z a z i o n e

∗ d e l f i g l i o d i i n d i c e ’ k ’ s i o t t i e n e a t t e n d e n d o un

∗ c a r a t t e r e d a l l a p i p e che l o c o l l e g a a l f i g l i o d i

∗ i n d i c e ’ k −1 ’. ∗/

Npipe = N; /∗ una p i p e i n u s c i t a da o g n i f i g l i o ∗/

P f d s = m a l l o c ( Npipe ∗ s i z e o f ( p i p e t ) ) ; i f ( P f d s==NULL) {

z p r i n t f ( 2 , ” I m p o s s i b i l e a l l o c a r e P f d s \n” ) ; return ( 1 ) ;

}

f o r ( i =0; i <Npipe ; i ++) { i f ( p i p e ( P f d s [ i ] ) ! = 0 ) {

z p r i n t f ( 2 , ” I m p o s s i b i l e c r e a r e l a p i p e %d\n” , i ) ; return ( 1 ) ;

} }

/∗ C r e a z i o n e p r o c e s s i f i g l i :

∗ d a l t e s t o , b i s o g n a c r e a r e un p r o c e s s o f i g l i o p e r o g n i c a r a t t e r e

∗ q u i n d i N f i g l i=N

∗ V i s t o che i l p a d r e d e v e stampare i v a l o r i d i u s c i t a d e i p r o c e s s i

∗ f i g l i , s i devono memorizzare i p i d i n o r d i n e d i i n d i c e p e r p o i

∗ a b b i n a r e i r i s u l t a t i d e l l e w a i t . L ’ a r r a y d i p i d d e v e e s s e r e

∗ a l l o c a t o dinamicamente ∗/

N f i g l i = N;

P i d s=m a l l o c ( N f i g l i ∗ s i z e o f ( i n t ) ) ; i f ( P i d s==NULL) {

z p r i n t f ( 2 , ” I m p o s s i b i l e a l l o c a r e P i d s \n” ) ; return ( 1 ) ;

}

f o r ( i =0; i <N f i g l i ; i ++) { P i d s [ i ]= f o r k ( ) ;

switch ( P i d s [ i ] ) {

case 0 : /∗ f i g l i o d i i n d i c e i ∗/

return ( f i g l i o ( i ) ) ; /∗ chiamo f u n z i o n e f i g l i o e uso v a l o r e d i r i t o r n o come e x i t d e l p r o c e s s o ∗/

case −1:

z p r i n t f ( 2 , ” I m p o s s i b i l e f o r k a r e i l p r o c e s s o %d\n” , i ) ; return ( 1 ) ;

break ; }

(9)

#i f d e f DEBUG

/∗ s o l o i l p r o c e s s o p a d r e e s e g u e q u e s t e l i n e e ∗/

z p r i n t f ( 1 , ” F o r k a t o p r o c e s s o %d p e r i n d i c e %d\n” , P i d s [ i ] , i ) ;

#endif }

/∗ I l p a d r e non u t i l i z z a n e s s u n a p i p e i n quando l a s i n c r o n i z z a z i o n e

∗ v i e n e f a t t a t o t a l m e n t e f r a i f i g l i . E v e n t u a l m e n t e (ma c i sono

∗ anche a l t r i modi ) i l p a d r e puo ’ d a r e i l v i a a l primo f i g l i o .

∗ U t i l i z z i a m o q u e s t a p o s s i b i l i t a ’ ed u t i l i z z i a m o un s i n g o l o

∗ c a r a t t e r e memorizzato i n ok p e r l ’ i n v i o ∗/

i f ( w r i t e ( P f d s [ 0 ] [ SCRIT] , & ok , 1 ) ! = 1 ) { /∗ c o n t r o l l o d i s c r i t t u r a a v v e n u t a ∗/

z p r i n t f ( 2 , ” I m p o s s i b i l e i n v i a r e su %d\n” , P f d s [ 0 ] [ SCRIT ] ) ; return ( 1 ) ;

}

/∗ o r a c h i u d i a m o t u t t e l e p i p e i n u t i l i z z a t e d a l padre , compresa

∗ q u e l l a i n c u i abbiamo appena s c r i t t o ( i l c a r a t t e r e rimane ! ) ∗/

f o r ( i =0; i <Npipe ; i ++) { c l o s e ( P f d s [ i ] [ SCRIT ] ) ; c l o s e ( P f d s [ i ] [ LETT ] ) ; }

/∗ Recupero d e l l e i n f o r m a z i o n i d a i p r o c e s s i f i g l i t r a m i t e l a w a i t ∗/

f o r ( i =0; i <N f i g l i ; i ++) { i n t p i d x ;

i n t s t a t u s ;

p i d x = w a i t (& s t a t u s ) ;

/∗ a b b i n a m e n t o d e l l e i n f o r m a z i o n i a l l ’ i n d i c e d e l f i g l i o ∗/

f o r ( j =0; j <N f i g l i ; j ++) { i f ( p i d x==P i d s [ j ] ) {

i f (WEXITSTATUS( s t a t u s )==255) {

/∗ c o n v e n z i o n e : s e g n a l a z i o n e d ’ e r r o r e ∗/

z p r i n t f ( 1 ,

” I l f i g l i o c h e c e r c a i l c a r a t t e r e %c ha i n c o n t r a t o un e r r o r e \n” , C [ j ] ) ;

} e l s e {

z p r i n t f ( 1 ,

” I l f i g l i o c h e c e r c a i l c a r a t t e r e %c ha t r o v a t o %d l i n e e \n” , C [ j ] ,WEXITSTATUS( s t a t u s ) ) ;

} } } }

return ( 0 ) ; }

/∗ F un z io n e f i g l i o ∗/

i n t f i g l i o ( i n t i n d i c e ) {

/∗ Ogni f i g l i o d e v e c e r c a r e l e o c c o r r e n z e d i C[ i ] n e l f i l e F ,

∗ q u i n d i i l f i l e NON d e v e e s s e r e c o n d i v i s o ma a p e r t o i n d i p e n d e n t e m e n t e

∗ da o g n i f i g l i o ∗/

i n t f d ;

i n t linenum ; /∗ c o n t a t o r e d i l i n e a c o r r e n t e ∗/

char ch ; /∗ c a r a t t e r e d i a p p o g g i o ∗/

(10)

i n t r e t v a l ; /∗ v a l o r e d i r i t o r n o ∗/

i n t nr ; /∗ numero d i c a r a t t e r i l e t t i d a l l a r e a d ∗/

i n t f l a g ; /∗ s e 0 c a r a t t e r e non t r o v a t o , s e 1 t r o v a t o ∗/

i n t nrp ; /∗ numero d i c a r l e t t i da r e a d su p i p e ∗/

char dummy ; /∗ c a r a t t e r e d i a p p o g g i o p e r l e t t / s c r i t t p i p e ∗/

i n t i ; /∗ un c o n t a t o r e ∗/

i n t p i p e d i s i n c ; /∗ i n d i c e d e l l a p i p e d i s i n c r o n i z z a z i o n e da c u i f a r e l a r e a d ∗/

/∗ C h i u s u r a d e i l a t i d e l l e p i p e p e r e v i t a r e i l d e a d l o c k quando

∗ un f i g l i o t e r m i n a prima d e g l i a l t r i e non puo ’ p r o s e g u i r e

∗ n e l l ’ a t t i v i t a ’ d i s i n c r o n i z z a z i o n e . Se almeno i l a t i

∗ d i s c r i t t u r a sono p o s s e d u t i ognuno da un s o l o p r o c e s s o

∗ l a t e r m i n a z i o n e d i q u e s t o p r o v o c a un comportamento non

∗ b l o c c a n t e p e r l a r e a d ∗/

f o r ( i =0; i <Npipe ; i ++) {

/∗ c h i u d o i l a t i d i s c r i t t u r a s e non e ’ l a p i p e

∗ che usa q u e s t o f i g l i o ∗/

i f ( i n d i c e != N f i g l i −1) { i f ( i ! = ( i n d i c e +1)) {

c l o s e ( P f d s [ i ] [ SCRIT ] ) ; }

} e l s e {

i f ( i ! = 0 ) {

c l o s e ( P f d s [ i ] [ SCRIT ] ) ; }

} }

f d=open (F ,O RDONLY ) ; i f ( fd <0) {

#i f d e f DEBUG

z p r i n t f ( 2 , ” I m p o s s i b i l e a p r i r e i l f i l e %s \n” ,F ) ;

#endif

return ( − 1 ) ; }

/∗ i l f i l e d e v e e s s e r e l e t t o p e r l i n e e ∗/

linenum =1; /∗ prima l i n e a ∗/

r e t v a l =0; /∗ l i n e e c h e s o d d i s f a n o =0 ∗/

f l a g =0;

/∗ s i n c r o n i z z a z i o n e ’ e s t e s a ’ i n g r a d o d i a s s i c u r a r c i l ’ a l t e r n a n z a d e l l e

∗ i n f o r m a z i o n i anche i n s e g u i t o a l l a t e r m i n a z i o n e d i uno o p i u ’ f i g l i

∗ s i usa una v a r i a b i l e p e r memorizzare l ’ i n d i c e d e l l a p i p e da c u i

∗ a t t e n d e r e l ’ ok . Se l a r e a d da t a l e i n d i c e r e s t i t u i s c e 0 −> a l l o r a i l

∗ f i g l i o r e l a t i v o e ’ t e r m i n a t o e b i s o g n a ’ a g g a n c i a r s i ’ a l p r e c e d e n t e .

∗ Nel c a s o e s t r e m o i n c u i un s o l o p r o c e s s o f i g l i o rimanga i n e s s e r e ,

∗ l a p i p e d i l e t t u r a e q u e l l a d i s c r i t t u r a vanno a c o i n c i d e r e

∗ s b l o c c a n d o c o n t i n u a m e n t e l ’ o u t p u t d i t a l e p r o c e s s o ∗/

p i p e d i s i n c = i n d i c e ; /∗ i n i z i a m o con q u e l l a ’ c a n o n i c a ’ ∗/

f o r ( ; ; ) {

nr=r e a d ( fd ,& ch , 1 ) ; i f ( nr==0) {

return ( r e t v a l ) ; }

(11)

i f ( nr <0) { /∗ e r r o r e ∗/

#i f d e f DEBUG

z p r i n t f ( 2 , ” I m p o s s i b i l e l e g g e r e d a l f i l e %s \n” ,F ) ;

#endif

return ( − 1 ) ; }

/∗ c a r a t t e r e l e t t o , c o n t r o l l o s e f i n e l i n e a ∗/

i f ( ch== ’ \n ’ ) { linenum++;

f l a g =0;

}

/∗ d a l t e s t o : s e t r o v o i l c a r a t t e r e a s s e g n a t o C[ i n d i c e ] , d e v o r i p o r t a r e

∗ i l numero d i l i n e a su s t d o u t . Se i l c a r a t t e r e s i t r o v a p i u ’

∗ v o l t e n e l l a s t e s s a l i n e a devo r i p o r t a r e i l numero s o l o

∗ una v o l t a , q u i n d i uso un f l a g che c o n t r o l l o a f i n e l i n e a ∗/

i f ( ( ch==C [ i n d i c e ])&& f l a g ==0) { f l a g =1;

r e t v a l ++; /∗ i n c r e m e n t o c o n t a t o r e ∗/

/∗ a g g i u n g o s i n c r o n i z z a z i o n e , a t t e n d o c a r a t t e r e da p i p e

∗ con i n d i c e p i p e d i s i n c e g e s t i s c o l ’ e v e n t u a l e

∗ t e r m i n a z i o n e d e l f i g l i o a s s o c i a t o ∗/

f o r ( ; ; ) {

nrp=r e a d ( P f d s [ p i p e d i s i n c ] [ LETT] , &dummy , 1 ) ; i f ( nrp==0) {

/∗ p i p e c h i u s a , a g g a n c i a m o c i a l f i g l i o p r e c e d e n t e ∗/

i f ( p i p e d i s i n c >0) { p i p e d i s i n c −−;

} e l s e {

p i p e d i s i n c=Npipe −1;

}

continue ; }

i f ( nrp==−1) {

/∗ e r r o r e , s e g n a l a r e ∗/

#i f d e f DEBUG

z p r i n t f ( 2 , ” E r r o r e p i p e d i s i n c r o n i z z a z i o n e \n” ) ;

#endif

return ( − 1 ) ; }

break ; }

/∗ s e sono q u i p o s s o s c r i v e r e ∗/

z p r i n t f ( 1 , ” L i n e a %d c o n t i e n e %c \n” , linenum , C [ i n d i c e ] ) ; /∗ 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 : l ’ i n d i c e d e l l a p i p e

∗ i n c u i s c r i v e r e e ’ i n d i c e +1 a meno che no s i t r a t t i d e l l ’ u l t i m o

∗ f i g l i o ( q u e l l o con i n d i c e =( N f i g l i −1)) che d e v e s c r i v e r e s u l l a

∗ p i p e d i i n d i c e 0 ∗/

i f ( i n d i c e != N f i g l i −1) {

w r i t e ( P f d s [ i n d i c e + 1 ] [ SCRIT] , &dummy , 1 ) ; } e l s e {

w r i t e ( P f d s [ 0 ] [ SCRIT] , &dummy , 1 ) ; }

}

(12)

}

/∗ mai q u i ! ∗/

return ( − 1 ) ; }

void z p r i n t f ( i n t fd , const char ∗ fmt , . . . ) { /∗ p r i n t f wrapper u s i n g w r i t e i n s t e a d ∗/

s t a t i c char msg [ 2 5 6 ] ; v a l i s t ap ;

i n t n ;

v a s t a r t ( ap , fmt ) ;

n=v s n p r i n t f ( msg , 2 5 6 , fmt , ap ) ; w r i t e ( fd , msg , n ) ;

v a e n d ( ap ) ; }

3. Invertire l’ordine di sincronizzazione dei figli nell’esercizio es102.c (es103.c) Soluzione:

F[N−1]

Parent

F[0] F[1] F[N−1]

N wait()

pipes[N−1]

pipes[2]

pipes[N−1]

pipes[1] pipes[2]

pipes[0]

F[1]

F[1]

pipes[1]

pipes[1]

/∗ f i l e : e s 1 0 3 . c

∗ j o b : i n v e r s i o n e d ’ o r d i n e su e s 1 0 2 . c

∗/

#include <s t d i o . h>

#include < s t d l i b . h>

#include <u n i s t d . h>

#include <s y s / t y p e s . h>

#include <s y s / w a i t . h>

#include <s y s / s t a t . h>

#include < f c n t l . h>

#include <s t d a r g . h>

(13)

typedef i n t p i p e t [ 2 ] ; /∗ t i p o p e r p i p e ∗/

#define SCRIT 1

#define LETT 0

char ∗F ; /∗ Nome d e l f i l e , v a r i a b i l e g l o b a l e ∗/

i n t N; /∗ Numero d i c a r a t t e r i ∗/

char ∗C ; /∗ E l e n c o d e i c a r a t t e r i , a l l o c a z i o n e d i n a m i c a ∗/

i n t Npipe ; /∗ Numero d i p i p e da c r e a r e ∗/

p i p e t ∗ P f d s ; /∗ Array d i p i p e , a l l o c a z i o n e d i n a m i c a ∗/

i n t N f i g l i ; /∗ Numero d i f i g l i da f o r k a r e ∗/

i n t ∗ P i d s ; /∗ Array d i p i d , a l l o c a z i o n e d i n a m i c a ∗/

/∗ a b b i n a m e n t o s n p r i n t f+w r i t e ∗/

void z p r i n t f ( i n t fd , const char ∗ fmt , . . . ) ; /∗ 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 ) ;

char ok= ’Q ’ ; /∗ c a r a t t e r e ( c a s u a l e ) c h e i n v i a m o s u l l a p i p e p e r l a s i n c r o n i z z a z i o n e ∗/

i n t main ( i n t a r g c , char ∗∗ argv , char ∗∗ envp ) { i n t i , j ; /∗ q u a l c h e c o n t a t o r e ∗/

/∗ D e t e r m i n a z i o n e d e i d a t i d a l l a command l i n e ∗/

switch ( a r g c ) { case 0 : case 1 : case 2 :

z p r i n t f ( 2 , ” I n s e r i r e i l nome d i f i l e ed almeno un c a r a t t e r e \n” ) ; return ( 1 ) ;

}

F = a r g v [ 1 ] ;

N = a r g c −2; /∗ a r g c v a l e 1 s e non c i sono a r g o m e n t i ∗/

C = m a l l o c (N∗ s i z e o f ( char ) ) ; i f (C==NULL) {

z p r i n t f ( 2 , ” I m p o s s i b i l e a l l o c a r e C\n” ) ; return ( 1 ) ;

}

f o r ( i =0; i <N; i ++) {

C [ i ]= a r g v [ i + 2 ] [ 0 ] ; /∗ p r e n d o i l primo c a r a t t e r e d e l l a s t r i n g a a r g v [ i +2] ∗/

}

#i f d e f DEBUG

z p r i n t f ( 1 , ”Nome d e l f i l e : %s \n” ,F ) ; z p r i n t f ( 1 , ”Numero d i c a r a t t e r i %d\n” ,N ) ; f o r ( i =0; i <N; i ++) {

z p r i n t f ( 1 , ” C a r a t t e r e d i i n d i c e %d = %c \n” , i , C [ i ] ) ; }

#endif

/∗ P r e d i s p o s i z i o n e d e l s i s t e m a d i s i n c r o n i z z a z i o n e

∗ f r a i p r o c e s s i f i g l i : s i u t i l i z z a una p i p e p e r

∗ c o l l e g a r e o g n i f i g l i o a l s u c c e s s i v o ; l a s i n c r o n i z z a z i o n e

∗ d e l f i g l i o d i i n d i c e ’ k ’ s i o t t i e n e a t t e n d e n d o un

∗ c a r a t t e r e d a l l a p i p e che l o c o l l e g a a l f i g l i o d i

(14)

∗ i n d i c e ’ k −1 ’. ∗/

Npipe = N; /∗ una p i p e i n u s c i t a da o g n i f i g l i o ∗/

P f d s = m a l l o c ( Npipe ∗ s i z e o f ( p i p e t ) ) ; i f ( P f d s==NULL) {

z p r i n t f ( 2 , ” I m p o s s i b i l e a l l o c a r e P f d s \n” ) ; return ( 1 ) ;

}

f o r ( i =0; i <Npipe ; i ++) { i f ( p i p e ( P f d s [ i ] ) ! = 0 ) {

z p r i n t f ( 2 , ” I m p o s s i b i l e c r e a r e l a p i p e %d\n” , i ) ; return ( 1 ) ;

} }

/∗ C r e a z i o n e p r o c e s s i f i g l i :

∗ d a l t e s t o , b i s o g n a c r e a r e un p r o c e s s o f i g l i o p e r o g n i c a r a t t e r e

∗ q u i n d i N f i g l i=N

∗ V i s t o che i l p a d r e d e v e stampare i v a l o r i d i u s c i t a d e i p r o c e s s i

∗ f i g l i , s i devono memorizzare i p i d i n o r d i n e d i i n d i c e p e r p o i

∗ a b b i n a r e i r i s u l t a t i d e l l e w a i t . L ’ a r r a y d i p i d d e v e e s s e r e

∗ a l l o c a t o dinamicamente ∗/

N f i g l i = N;

P i d s=m a l l o c ( N f i g l i ∗ s i z e o f ( i n t ) ) ; i f ( P i d s==NULL) {

z p r i n t f ( 2 , ” I m p o s s i b i l e a l l o c a r e P i d s \n” ) ; return ( 1 ) ;

}

f o r ( i =0; i <N f i g l i ; i ++) { P i d s [ i ]= f o r k ( ) ;

switch ( P i d s [ i ] ) {

case 0 : /∗ f i g l i o d i i n d i c e i ∗/

return ( f i g l i o ( i ) ) ; /∗ chiamo f u n z i o n e f i g l i o e uso v a l o r e d i r i t o r n o come e x i t d e l p r o c e s s o ∗/

case −1:

z p r i n t f ( 2 , ” I m p o s s i b i l e f o r k a r e i l p r o c e s s o %d\n” , i ) ; return ( 1 ) ;

break ; }

#i f d e f DEBUG

/∗ s o l o i l p r o c e s s o p a d r e e s e g u e q u e s t e l i n e e ∗/

z p r i n t f ( 1 , ” F o r k a t o p r o c e s s o %d p e r i n d i c e %d\n” , P i d s [ i ] , i ) ;

#endif }

/∗ I l p a d r e non u t i l i z z a n e s s u n a p i p e i n quando l a s i n c r o n i z z a z i o n e

∗ v i e n e f a t t a t o t a l m e n t e f r a i f i g l i . E v e n t u a l m e n t e (ma c i sono

∗ anche a l t r i modi ) i l p a d r e puo ’ d a r e i l v i a a l primo f i g l i o .

∗ U t i l i z z i a m o q u e s t a p o s s i b i l i t a ’ ed u t i l i z z i a m o un s i n g o l o

∗ c a r a t t e r e memorizzato i n ok p e r l ’ i n v i o ∗/

i f ( w r i t e ( P f d s [ 0 ] [ SCRIT] , & ok , 1 ) ! = 1 ) { /∗ c o n t r o l l o d i s c r i t t u r a a v v e n u t a ∗/

z p r i n t f ( 2 , ” I m p o s s i b i l e i n v i a r e su %d\n” , P f d s [ 0 ] [ SCRIT ] ) ; return ( 1 ) ;

}

/∗ o r a c h i u d i a m o t u t t e l e p i p e i n u t i l i z z a t e d a l padre , compresa

∗ q u e l l a i n c u i abbiamo appena s c r i t t o ( i l c a r a t t e r e rimane ! ) ∗/

(15)

f o r ( i =0; i <Npipe ; i ++) { c l o s e ( P f d s [ i ] [ SCRIT ] ) ; c l o s e ( P f d s [ i ] [ LETT ] ) ; }

/∗ Recupero d e l l e i n f o r m a z i o n i d a i p r o c e s s i f i g l i t r a m i t e l a w a i t ∗/

f o r ( i =0; i <N f i g l i ; i ++) { i n t p i d x ;

i n t s t a t u s ;

p i d x = w a i t (& s t a t u s ) ;

/∗ a b b i n a m e n t o d e l l e i n f o r m a z i o n i a l l ’ i n d i c e d e l f i g l i o ∗/

f o r ( j =0; j <N f i g l i ; j ++) { i f ( p i d x==P i d s [ j ] ) {

i f (WEXITSTATUS( s t a t u s )==255) {

/∗ c o n v e n z i o n e : s e g n a l a z i o n e d ’ e r r o r e ∗/

z p r i n t f ( 1 ,

” I l f i g l i o c h e c e r c a i l c a r a t t e r e %c ha i n c o n t r a t o un e r r o r e \n” , C [ j ] ) ;

} e l s e {

z p r i n t f ( 1 ,

” I l f i g l i o c h e c e r c a i l c a r a t t e r e %c ha t r o v a t o %d l i n e e \n” , C [ j ] ,WEXITSTATUS( s t a t u s ) ) ;

} } } }

return ( 0 ) ; }

/∗ F un z io n e f i g l i o ∗/

i n t f i g l i o ( i n t i n d i c e ) {

/∗ Ogni f i g l i o d e v e c e r c a r e l e o c c o r r e n z e d i C[ i ] n e l f i l e F ,

∗ q u i n d i i l f i l e NON d e v e e s s e r e c o n d i v i s o ma a p e r t o i n d i p e n d e n t e m e n t e

∗ da o g n i f i g l i o ∗/

i n t f d ;

i n t linenum ; /∗ c o n t a t o r e d i l i n e a c o r r e n t e ∗/

char ch ; /∗ c a r a t t e r e d i a p p o g g i o ∗/

i n t r e t v a l ; /∗ v a l o r e d i r i t o r n o ∗/

i n t nr ; /∗ numero d i c a r a t t e r i l e t t i d a l l a r e a d ∗/

i n t f l a g ; /∗ s e 0 c a r a t t e r e non t r o v a t o , s e 1 t r o v a t o ∗/

i n t nrp ; /∗ numero d i c a r l e t t i da r e a d su p i p e ∗/

char dummy ; /∗ c a r a t t e r e d i a p p o g g i o p e r l e t t / s c r i t t p i p e ∗/

i n t i ; /∗ un c o n t a t o r e ∗/

i n t p i p e d i s i n c ; /∗ i n d i c e d e l l a p i p e d i s i n c r o n i z z a z i o n e da c u i f a r e l a r e a d ∗/

/∗ C h i u s u r a d e i l a t i d e l l e p i p e p e r e v i t a r e i l d e a d l o c k quando

∗ un f i g l i o t e r m i n a prima d e g l i a l t r i e non puo ’ p r o s e g u i r e

∗ n e l l ’ a t t i v i t a ’ d i s i n c r o n i z z a z i o n e . Se almeno i l a t i

∗ d i s c r i t t u r a sono p o s s e d u t i ognuno da un s o l o p r o c e s s o

∗ l a t e r m i n a z i o n e d i q u e s t o p r o v o c a un comportamento non

∗ b l o c c a n t e p e r l a r e a d ∗/

f o r ( i =0; i <Npipe ; i ++) {

/∗ c h i u d o i l a t i d i s c r i t t u r a s e non e ’ l a p i p e

(16)

∗ che usa q u e s t o f i g l i o ∗/

i f ( i ! = ( i n d i c e ) ) {

c l o s e ( P f d s [ i ] [ SCRIT ] ) ; }

}

f d=open (F ,O RDONLY ) ; i f ( fd <0) {

#i f d e f DEBUG

z p r i n t f ( 2 , ” I m p o s s i b i l e a p r i r e i l f i l e %s \n” ,F ) ;

#endif

return ( − 1 ) ; }

/∗ i l f i l e d e v e e s s e r e l e t t o p e r l i n e e ∗/

linenum =1; /∗ prima l i n e a ∗/

r e t v a l =0; /∗ l i n e e c h e s o d d i s f a n o =0 ∗/

f l a g =0;

/∗ s i n c r o n i z z a z i o n e ’ e s t e s a ’ i n g r a d o d i a s s i c u r a r c i l ’ a l t e r n a n z a d e l l e

∗ i n f o r m a z i o n i anche i n s e g u i t o a l l a t e r m i n a z i o n e d i uno o p i u ’ f i g l i

∗ s i usa una v a r i a b i l e p e r memorizzare l ’ i n d i c e d e l l a p i p e da c u i

∗ a t t e n d e r e l ’ ok . Se l a r e a d da t a l e i n d i c e r e s t i t u i s c e 0 −> a l l o r a i l

∗ f i g l i o r e l a t i v o e ’ t e r m i n a t o e b i s o g n a ’ a g g a n c i a r s i ’ a l p r e c e d e n t e .

∗ Nel c a s o e s t r e m o i n c u i un s o l o p r o c e s s o f i g l i o rimanga i n e s s e r e ,

∗ l a p i p e d i l e t t u r a e q u e l l a d i s c r i t t u r a vanno a c o i n c i d e r e

∗ s b l o c c a n d o c o n t i n u a m e n t e l ’ o u t p u t d i t a l e p r o c e s s o ∗/

p i p e d i s i n c = ( i n d i c e +1)%Npipe ; /∗ i n i z i a m o con q u e l l a ’ c a n o n i c a ’ ∗/

f o r ( ; ; ) {

nr=r e a d ( fd ,& ch , 1 ) ; i f ( nr==0) {

return ( r e t v a l ) ; }

i f ( nr <0) { /∗ e r r o r e ∗/

#i f d e f DEBUG

z p r i n t f ( 2 , ” I m p o s s i b i l e l e g g e r e d a l f i l e %s \n” ,F ) ;

#endif

return ( − 1 ) ; }

/∗ c a r a t t e r e l e t t o , c o n t r o l l o s e f i n e l i n e a ∗/

i f ( ch== ’ \n ’ ) { linenum++;

f l a g =0;

}

/∗ d a l t e s t o : s e t r o v o i l c a r a t t e r e a s s e g n a t o C[ i n d i c e ] , d e v o r i p o r t a r e

∗ i l numero d i l i n e a su s t d o u t . Se i l c a r a t t e r e s i t r o v a p i u ’

∗ v o l t e n e l l a s t e s s a l i n e a devo r i p o r t a r e i l numero s o l o

∗ una v o l t a , q u i n d i uso un f l a g che c o n t r o l l o a f i n e l i n e a ∗/

i f ( ( ch==C [ i n d i c e ])&& f l a g ==0) { f l a g =1;

r e t v a l ++; /∗ i n c r e m e n t o c o n t a t o r e ∗/

/∗ a g g i u n g o s i n c r o n i z z a z i o n e , a t t e n d o c a r a t t e r e da p i p e

∗ con i n d i c e p i p e d i s i n c e g e s t i s c o l ’ e v e n t u a l e

∗ t e r m i n a z i o n e d e l f i g l i o a s s o c i a t o ∗/

f o r ( ; ; ) {

(17)

nrp=r e a d ( P f d s [ p i p e d i s i n c ] [ LETT] , &dummy , 1 ) ; i f ( nrp==0) {

/∗ p i p e c h i u s a , a g g a n c i a m o c i a l f i g l i o s u c c e s s i v o ∗/

i f ( p i p e d i s i n c <(Npipe −1)) { p i p e d i s i n c ++;

} e l s e {

p i p e d i s i n c =0;

}

continue ; }

i f ( nrp==−1) {

/∗ e r r o r e , s e g n a l a r e ∗/

#i f d e f DEBUG

z p r i n t f ( 2 , ” E r r o r e p i p e d i s i n c r o n i z z a z i o n e \n” ) ;

#endif

return ( − 1 ) ; }

break ; }

/∗ s e sono q u i p o s s o s c r i v e r e ∗/

z p r i n t f ( 1 , ” L i n e a %d c o n t i e n e %c \n” , linenum , C [ i n d i c e ] ) ; /∗ o r a do i l v i a a l f i g l i o c h e d e v e e s e g u i r e l ’ o p e r a z i o n e

∗ dopo q u e l l o c o r r e n t e , o v v e r o i l f i g l i o a v e n t e i n d i c e minore

∗ d i 1 ( o l ’ u l t i m o n e l c a s o d e l f i g l i o con i n d i c e ==0):

∗ l ’ i n d i c e d e l l a p i p e i n c u i s c r i v e r e e ’ u g u a l e a l l ’ i n d i c e

∗ d e l f i g l i o ∗/

w r i t e ( P f d s [ i n d i c e ] [ SCRIT] , &dummy , 1 ) ; }

}

/∗ mai q u i ! ∗/

return ( − 1 ) ; }

void z p r i n t f ( i n t fd , const char ∗ fmt , . . . ) { /∗ p r i n t f wrapper u s i n g w r i t e i n s t e a d ∗/

s t a t i c char msg [ 2 5 6 ] ; v a l i s t ap ;

i n t n ;

v a s t a r t ( ap , fmt ) ;

n=v s n p r i n t f ( msg , 2 5 6 , fmt , ap ) ; w r i t e ( fd , msg , n ) ;

v a e n d ( ap ) ; }

4. Creiamo un sorgente C es104.c che possa servire come base di partenza per la realizzazione di appli- cazioni concorrenti.

Soluzione:

/∗ Esempio d i b a s e comune ∗/

#include <s t d i o . h>

#include <u n i s t d . h>

#include < s t d l i b . h>

#include <s y s / w a i t . h>

#include <s t d a r g . h>

/∗ Numero d i p i p e da c r e a r e ∗/

(18)

i n t n p i p e ;

/∗ Numero d i p r o c e s s i f i g l i ∗/

i n t n f i g l i ;

/∗ t i p o d i d a t o p e r c o n t e n e r e i f i l e d e s c r i p t o r s

∗ d i una p i p e ∗/

typedef i n t p i p e t [ 2 ] ;

/∗ c o n t e n i t o r e p e r i f i l e d e s c r i p t o r s d i t u t t e

∗ l e p i p e u t i l i z z a t e ∗/

p i p e t ∗ p i p e f d s ;

/∗ p r o t o t i p o f u n z i o n e p r o c e s s o f i g l i o , da p e r s o n a l i z z a r e ∗/

i n t f i g l i o ( i n t a r g ) ; /∗ p r o t o t i p o z p r i n t f ∗/

void z p r i n t f ( i n t fd , const char ∗ fmt , . . . ) ; i n t main ( i n t a r g c , char ∗∗ a r g v ) {

i n t p i d f ; i n t s t a t u s ; i n t i ; n p i p e =1;

n f i g l i =1;

/∗ a l l o c a z i o n e memoria d i n a m i c a p e r p i p e f d s ∗/

p i p e f d s=m a l l o c ( n p i p e ∗ s i z e o f ( p i p e t ) ) ; i f ( p i p e f d s ==0) {

p r i n t f ( ” E r r o r e \n” ) ; return ( 1 ) ;

}

/∗ c r e a z i o n e d e l l e p i p e ∗/

f o r ( i =0; i <n p i p e ; i ++) { i f ( p i p e ( p i p e f d s [ i ] ) ! = 0 ) {

p r i n t f ( ” E r r o r e \n” ) ; return ( 1 ) ;

} }

/∗ c r e a z i o n e d e i p r o c e s s i f i g l i ∗/

f o r ( i =0; i < n f i g l i ; i ++) { switch ( f o r k ( ) ) {

case 0 :

/∗ i n v o c a z i o n e d e l l a f u n z i o n e f i g l i o

∗ e t e r m i n a z i o n e d e l p r o c e s s o con

∗ e x i t v a l u e u g u a l e a l r e t u r n v a l u e

∗ d e l l a f u n z i o n e f i g l i o ( ) ∗/

return ( f i g l i o ( i ) ) ; case −1:

p r i n t f ( ” E r r o r e \n” ) ; return ( 1 ) ;

d e f a u l t :

/∗ s o l o d a l p a d r e ∗/

; }

}

/∗ c i c l o e s e g u i t o d a l s o l o p r o c e s s o p a d r e

∗ p e r r e c u p e r a r e l e i n f o d i t e r m i n a z i o n e

∗ d e i p r o c e s s i f i g l i ∗/

f o r ( i =0; i < n f i g l i ; i ++) {

(19)

p i d f=w a i t (& s t a t u s ) ; }

/∗ e x i t v a l u e d e l p r o c e s s o p a d r e ∗/

return ( 0 ) ; }

/∗ f u n z i o n e p r o c e s s o f i g l i o , d e f i n i z i o n e ∗/

i n t f i g l i o ( i n t a r g ) { return ( 0 ) ;

}

/∗ a b b i n a m e n t o s n p r i n t f+w r i t e ∗/

void z p r i n t f ( i n t fd , const char ∗ fmt , . . . ) { s t a t i c char msg [ 2 5 6 ] ;

v a l i s t ap ; i n t n ;

v a s t a r t ( ap , fmt ) ;

n=v s n p r i n t f ( msg , 2 5 6 , fmt , ap ) ; w r i t e ( fd , msg , n ) ;

v a e n d ( ap ) ; }

5. Creiamo un Makefile per la compilazione dell’esempio Soluzione:

e s e r c i z i o : e s 1 0 4 . c

g c c −Wall −o e s e r c i z i o e s 1 0 4 . c

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

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

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

Ogni processo figlio Pi deve, prima di creare il proprio nipote, creare un file FOut il cui nome deve risultare dalla concatenazione della stringa &#34;merge&#34; e della

Scrivere un programma che dato un codice libro visualizzi il titolo ed il numero dei suoi autori ed il nome ed email della sua