Title: Costruzione di una semplice Agenda telefonica Elettronica
1Costruzione di una semplice Agenda telefonica
Elettronica
- Esercizio sull'uso delle principali system call
Unix
2Agenda telefonica
- L'agenda e' costituita da un semplice file di
testo. Ogni riga e' formata da - Cognome nome numero-telefonico
- ad esempio
- Bollati Mario 0116792932
- Corelli Simona 0234743212
- Magni Giorgio 06431432143
- .......... ........... .................
3Comandi per gestire l'agenda
- cerca cognome
- stampa sul terminale la riga del file agenda che
contiene cognome - inserisci cognome nome numero-telefonico
- inserisce nel file agenda la riga formata da
cognome, nome e numero di telefono - rimuovi cognome
- rimuove dall'agenda la riga contenente cognome
4implementazione mediante demone e code di messaggi
coda delle richieste di accesso all'agenda
bassi mario 43214321 Carli Bruno 0143243 Massi
Rino 9434232 ....... ....... .............
file "agenda"
5Implementazione mediante demone e code di messaggi
- Il processo demone viene lanciato in back ground
e resta in attesa sulla coda delle richieste di
accesso all'agenda. - L'accesso al file "agenda" e' gestito unicamente
dal demone le varie operazioni sono così
automaticamente serializzate.
6Implementazione mediante demone e code di messaggi
- le tre operazioni possono essere richieste al
demone usando messaggi di tipo diverso (basta
usare un numero diverso per ogni tipo di
messaggio) - il processo richiedente attende sulla coda la
risposta del demone che restituisce il numero di
telefono (per cerca) o semplicemente segnala il
completamento dell'operazione (per inserisci e
rimuovi)
7Implementazione mediante demone e code di messaggi
- Come fare in modo che il demone comunichi
direttamente ed esclusivamente con il processo
che attende la sua risposta? - Basta inserire nella stringa del messaggio il
numero del processo richiedente pid. Il demone
risponde con un messaggio di tipo pid, che solo
il processo stesso puo' ricevere.
8Implementazione mediante semafori e accesso
diretto al file "agenda" in modo mutuamente
esclusivo
P
bassi mario 43214321 Carli Bruno 0143243 Massi
Rino 9434232 ....... ....... .............
area ad accesso mutuamente esclusivo
file "agenda"
V
9Implementazione mediante semafori e accesso
diretto al file "agenda"
- Le operazioni su "agenda" devono avvenire in
mutua esclusione, attraverso l'uso di un semaforo
binario inizializzato a 1 - ognuno dei tre programmi, per accedere al file
agenda deve prima eseguire una P sul semaforo, e
poi puo' aprire il file e leggerlo o modificarne
il contenuto. - Alla fine delle operazioni sul file il processo
deve eseguire una V sul semaforo prima di
terminare.
10Alcuni consigli
- Tenete tutti i programmi e il file agenda in
un'unica directory. - Come fanno i programmi a sapere l'identificatore
della coda o semaforo da usare? Un modo semplice
e' usare un file id_file per contere
l'identificativo della coda o del semaforo - nel caso della coda, e' il demone che preleva la
coda e scrive il suo identificatore dentro
id_file - Nel caso del semaforo, un programma ad hoc
preleva il semaforo, scrive il suo identificatore
dentro id_file e termina. - I programmi leggono dentro id_file per conoscere
l'identificatore da usare.
11Alcuni consigli
- C'e' pero' un modo piu' elegante per far usare ad
un insieme di programmi la coda (o il semaforo) - msgid msgget(KEY, IPC_CREAT 666)
- KEY e' un numero intero concordato da tutti i
programmi che vogliono usare la coda - Alla prima chiamata della msgget con KEY, viene
creata una nuova coda e il suo identificatore
msgid associato biunivocamente a KEY. - successivamente, qualsiasi altro programma che
chiama msgget con lo stesso valore di KEY riceve
il msgid associato a KEY.
12Alcuni consigli
- ad esempio, in un file mydef.h possiamo mettere
- define LA_NOSTRA_CODA 12345
- e in ogni programma che deve usare
LA_NOSTRA_CODA - include mydef.h
- ..... .....
- msgid msgget(LA_NOSTRA_CODA,IPC_CREAT666)
- Notate se 2 o piu' processi condividono lo
stesso padre, allora si puo' fare anche in un
altro modo - msgid msgget(getppid(), IPC_CREAT666)
13Alcuni consigli
- quando avete finito di provare i programmi,
ricordatevi di rimuovere le risorse prelevate (il
semaforo o la coda) e, se presente, di uccidere
il processo demone. - Per compilare un programma C
- gcc prog.c -o prog
14Alcuni consigli
- potete usare solo "istruzioni C", se preferite,
ma non scordatevi che puo' essere comodo usare
anche i comandi shell. - Ad esempio, per rimuovere la riga contentente
cognome - gt grep v cognome gt agenda.tmp
- gt mv agenda.tmp agenda
- la system call system puo' essere usata per
eseguire comandi shell da un programma C
15per provare il funzionamento dei programmi
- ovviamente lanciando direttamente i 3 comandi.
- potete pero' anche scrivere un programma che
ciclicamente sceglie uno tra i comandi cerca
inserisci e rimuovi e lo esegue. - per produrre l'effetto di piu' richieste di
accesso concorrente all'agenda, potete costruire
un programma che si forka 2 o 3 volte, e ogni
figlio esegue i comandi di uso dell'agenda.
16consigli sul funzionamento del progr. di
generazione delle richieste all'agenda
- ogni figlio esegue un ciclo un numero finito di
volte (ad esempio 100) oppure indefinitamente. - ad ogni ciclo
- sleep un tempo random di 1 o 2 secondi
- scegli in modo random uno dei tre comandi
- esegui comando
- comando puo' essere eseguito con una exec o piu'
semplicemente con una system
17consigli sul funzionamento del progr. di
generazione delle richieste all'agenda
- il padre dei due figli che inviano ciclicamente
le richieste puo' mettersi in attesa (wait) della
loro terminazione, e poi rimuovere le risorse (se
necessario uccidere il demone) e terminare. - soprattutto nel caso in cui i figli ciclano
all'infinito, potete inoltre prevedere un
meccanismo di gestione della terminazione
mediante signal e kill
18terminazione dell'intero sistema mediante signal
e kill
- il programma di generazione delle richieste
all'agenda definisce una procedura di
terminazione da eseguire alla ricezione di un
segnale inviato da terminale mediante kill - gt kill SIGUSR1 pid
- la procedura di terminazione rimuove le risorse
(coda o semaforo) e termina il programma.
ATTENZIONE e' possibile far terminare anche i
figli (e se necessario il demone)?
19struttura generale del programma
-
- termina(...)
- ...
- signal(termina,SIGUSR1)
- fork()
- if figlio for ()
- sleep(1,2) system(estrai,rimuovi,inserisci)
- else fork()
- if figlio for ()
- sleep(1,2) system(estrai,rimuovi,inserisci)
- else wait()
-