• Non ci sono risultati.

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

N/A
N/A
Protected

Academic year: 2021

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

Copied!
6
0
0

Testo completo

(1)

Lab. di Sistemi Operativi

Esercitazioni proposte per la lezione del 27 maggio 2011

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

1. 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 (completamento dell’esercizio della scorsa settimana)

2. Modificare il precedente sorgente (in es112.c) in modo che il segnale di broken pipe (man 7 signal:

SIGPIPE,13,Broken pipe) venga intercettato da un opportuno handler.

3. (facoltativo)Ottenere un ritardo con l’uso del segnale SIGARLM. Progettare un applicativo che si sospenda per 10 secondi senza utilizzare la funzione sleep().

4. Progettare un applicativo concorrente con due processi (padre e figlio) che si alternano nella scrittura su stdout mediante segnali (es114.c)

(2)

Soluzione

Esercitazioni proposte per la lezione del 27 maggio 2011

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

1. 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 (completamento dell’esercizio della scorsa settimana)

Soluzione:

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

∗ j o b : i d e n t i f i c a z i o n e d e l s e g n a l e b r o k e n 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 y s / t y p e s . h>

#include <s y s / w a i t . 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 n t s t ;

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

/∗ u t i l i z z i a m o l a f o r k p e r l a s c i a r e a l p r o c e s s o f i g l i o

∗ l ’ incombenza d i s c r i v e r e s u l l a p i p e e r e c u p e r i a m o

∗ l e i n f o r m a z i o n i d i t e r m i n a z i o n e con l a w a i t ∗/

switch ( f o r k ( ) ) {

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

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

case −1: /∗ e r r o r e f o r k ∗/

w r i t e ( 2 , ” E r r o r e f o r k \n” , 1 2 ) ; /∗ su s t d e r r ∗/

return ( 1 ) ; break ;

(3)

}

/∗ p a d r e : a t t e n d o i l f i g l i o ( un ic o , non d e v o r e c u p e r a r e i l p i d ) ∗/

w a i t (& s t ) ;

i f (WIFEXITED( s t ) ) { /∗ t e r m i n a z i o n e ” n a t u r a l e ” , e x i t v a l u e v a l i d o ∗/

s n p r i n t f ( msg , s i z e o f ( msg ) , ” F i g l i o t o r n a %d\n” , WEXITSTATUS( s t ) ) ;

w r i t e ( 1 , msg , s t r l e n ( msg ) ) ;

} e l s e { /∗ t e r m i n a z i o n e f o r z a t a , no e x i t v a l u e ma i d s e g n a l e ∗/

s n p r i n t f ( msg , s i z e o f ( msg ) , ” F i g l i o t e r m i n a t o da %d\n” , WTERMSIG( s t ) ) ;

w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; }

return ( 0 ) ; }

2. Modificare il precedente sorgente (in es112.c) in modo che il segnale di broken pipe (man 7 signal:

SIGPIPE,13,Broken pipe) venga intercettato da un opportuno handler.

Soluzione:

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

∗ j o b : i n t e r c e t t a m e n t o d e l s e g n a l e b r o k e n 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 y s / t y p e s . h>

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

#include < s i g n a l . h>

char msg [ 2 5 6 ] ; char msg2 [ 2 5 6 ] ;

/∗ p r o t o t i p o d e l l ’ h a n d l e r ∗/

void i n t e r c e t t a ( i n t s e g n a l e ) ; 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 n t s t ;

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

/∗ u t i l i z z i a m o l a f o r k p e r l a s c i a r e a l p r o c e s s o f i g l i o

∗ l ’ incombenza d i s c r i v e r e s u l l a p i p e e r e c u p e r i a m o

∗ l e i n f o r m a z i o n i d i t e r m i n a z i o n e con l a w a i t ∗/

switch ( f o r k ( ) ) {

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

/∗ a g g a n c i o i n t e r c e t t a ( ) a SIGPIPE ∗/

s i g n a l ( SIGPIPE , i n t e r c e t t 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

(4)

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

case −1: /∗ e r r o r e f o r k ∗/

w r i t e ( 2 , ” E r r o r e f o r k \n” , 1 2 ) ; /∗ su s t d e r r ∗/

return ( 1 ) ; break ; }

/∗ p a d r e : a t t e n d o i l f i g l i o ( un ic o , non d e v o r e c u p e r a r e i l p i d ) ∗/

w a i t (& s t ) ;

i f (WIFEXITED( s t ) ) { /∗ t e r m i n a z i o n e ” n a t u r a l e ” , e x i t v a l u e v a l i d o ∗/

s n p r i n t f ( msg , s i z e o f ( msg ) , ” F i g l i o t o r n a %d\n” , WEXITSTATUS( s t ) ) ;

w r i t e ( 1 , msg , s t r l e n ( msg ) ) ;

} e l s e { /∗ t e r m i n a z i o n e f o r z a t a , no e x i t v a l u e ma i d s e g n a l e ∗/

s n p r i n t f ( msg , s i z e o f ( msg ) , ” F i g l i o t e r m i n a t o da %d\n” , WTERMSIG( s t ) ) ;

w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; }

return ( 0 ) ; }

void i n t e r c e t t a ( i n t s e g n a l e ) {

s n p r i n t f ( msg , s i z e o f ( msg ) , ” F i g l i o : i n t e r c e t t o %d\n” , s e g n a l e ) ;

w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; return ;

}

3. (facoltativo)Ottenere un ritardo con l’uso del segnale SIGARLM. Progettare un applicativo che si sospenda per 10 secondi senza utilizzare la funzione sleep().

Soluzione:

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

∗ j o b : a t t e s a t e m p o r i z z a t a

∗/

#include < s i g n a l . h>

#include <s t d i o . h>

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

#include < s t r i n g . h>

#include <s e t j m p . h>

void s i g f u n ( i n t s i g i d ) ; char msg [ 2 5 6 ] ;

j m p b u f s t a t o ; /∗ s a l v a t a g g i o s t a t o ∗/

i n t main ( i n t a r g c , char ∗∗ a r g v ) {

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

s i g n a l (SIGALRM, s i g f u n ) ; i f ( s e t j m p ( s t a t o ) ) {

/∗ s e non z e r o , a l l o r a t o r n o ∗/

s n p r i n t f ( msg , s i z e o f ( msg ) ,

(5)

” A t t e s a s c a d u t a \n” ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; } e l s e {

/∗ s e z e r o , primo p a s s a g g i o ∗/

s n p r i n t f ( msg , s i z e o f ( msg ) ,

” A t t e s a i n i z i a t a \n” ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; alarm ( 1 0 ) ;

s n p r i n t f ( msg , s i z e o f ( msg ) ,

” S v e g l i a i m p o s t a t a \n” ) ; w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; f o r ( ; ; ) {

p a u s e ( ) ; }

}

return ( 0 ) ; }

void s i g f u n ( i n t s i g i d ) { i f ( s i g i d==SIGALRM) {

longjmp ( s t a t o , 1 ) ; }

}

4. Progettare un applicativo concorrente con due processi (padre e figlio) che si alternano nella scrittura su stdout mediante segnali (es114.c)

Soluzione:

Parent

Figlio

SIGUSR1 SIGUSR1

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

∗ j o b : s i n c r o n i z z a z i o n e con s e g n a l i

∗/

#include < s i g n a l . h>

#include <s t d i o . h>

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

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

#include < s t r i n g . h>

void s i g f u n ( i n t s i g i d ) ; i n t f i g l i o ( void ) ;

v o l a t i l e i n t c o n s e n s o ; char msg [ 2 5 6 ] ;

(6)

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

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

s i g n a l ( SIGUSR1 , s i g f u n ) ;

c o n s e n s o =0; /∗ c o n s e n s o a s s e n t e ∗/

switch ( p i d f i g l i o =f o r k ( ) ) { case 0 : /∗ f i g l i o ∗/

return ( f i g l i o ( ) ) ; case −1: /∗ 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 f o r k ( ) \ n” ) ; w r i t e ( 2 , msg , s t r l e n ( msg ) ) ; return ( 1 ) ;

}

/∗ p a d r e ∗/

c o n s e n s o =1; /∗ i l p a d r e i n i z i a ∗/

f o r ( ; ; ) {

s n p r i n t f ( msg , s i z e o f ( msg ) , ” Padre \n” ) ; while ( ! c o n s e n s o ) p a u s e ( ) ;

w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; s l e e p ( 1 ) ; /∗ r a l l e n t a t o r e ! ∗/

c o n s e n s o =0; /∗ mi b l o c c o ∗/

k i l l ( p i d f i g l i o , SIGUSR1 ) ; /∗ s b l o c c o ∗/

}

return ( 0 ) ; }

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

s n p r i n t f ( msg , s i z e o f ( msg ) , ” F i g l i o \n” ) ; while ( ! c o n s e n s o ) p a u s e ( ) ;

w r i t e ( 1 , msg , s t r l e n ( msg ) ) ; s l e e p ( 1 ) ; /∗ r a l l e n t a t o r e ! ∗/

c o n s e n s o =0; /∗ mi b l o c c o ∗/

k i l l ( g e t p p i d ( ) , SIGUSR1 ) ; /∗ s b l o c c o ∗/

}

return ( 0 ) ; }

void s i g f u n ( i n t s i g i d ) { i f ( s i g i d==SIGUSR1 ) {

c o n s e n s o =1;

} }

Riferimenti

Documenti correlati

(40 minuti) es51p.sh Controllo parametri della parte shell del compito del 17 luglio 2007: La parte in Shell deve prevedere tre parametri: il primo deve essere il nome assoluto di

(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

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;

(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

LABORATORIO DI SISTEMI OPERATIVI (A.A. 2) I file prodotti devono essere collocati in un sottodirettorio della propria HOME directory che deve essere creato e avere