PDA

View Full Version : Semafori...domandina...


D4rkAng3l
28-05-2007, 18:06
Ciao,
stò studiando sistemi operativi (non sò se è meglio chiedere quì o nel 3d di informatica in scienza e tecnica...)

Stò vedendo la sezione del problema della mutua esclusione di una risorsa da parte di 2 o più processi che vi vorrebbero provare ad accedere in particolare il caso del modello PRODUTTORE-CONSUMATORE (con buffer di capacità unaria).

In pratica ho un processo PRODUTTORE che produce un messaggio da inserire nel buffer (di dimensione 1) ed un processo CONSUMATORE che deve estrarre il messaggio dal buffer ed usarlo per qualche suo scopo.

Quindi i vincoli sono che il PRODUTTORE non può inserire nulla nel buffer se questo è pieno ed il CONSUMATORE non può estrarre nulla dal buffer se questo è vuoto quindi devo risolvere un problema di sincronizzazione dei due processi mediante l'uso DI 2 semafori (in questo caso semafori binari) usando le rispettive primitive: wait e signal.

Quindi avrei una cosa del genere in pseudocodice:


Processo PRODUTTORE{
do{
<PRODUZIONE DEL NUOVO MESSAGGIO>;
wait(spazio_disponibile);
<DEPOSITO DEL MESSAGGIO NEL BUFFER>;
signal(messaggio_disponibile);
}while(!fine);
}

Processo CONSUMATORE{
do{
wait(messaggio_disponibile);
<PRELIEVO DEL MESSAGGIO DAL BUFFER>;
signal(spazio_disponibile);
<CONSUMO DEL MESSAGGIO>
}while(!fine);
}


Facendo l'ipotesir che il buffer è inizialmente vuoto bisogna settare i 2 valori dei semafori:
messaggio_disponibile a 0 e spazio_disponibile ad 1

In pratica il PRODUTTORE per prima cosa produce il messaggio da mettere nel buffer poi tramite la wait verifica se il valore numerico di spazio disponibile che sarà uguale ad 1 che tramite la wait viene dcrementato di 1 e viene eseguita la sezione critica di deposito del messaggio e successivamente viene resa disponibile tramite la signal la risorsa al processo consumatore che potrà estrarre dal buffer.

Ora visto che i 2 processi possono sovrapporsi nel tempo tra loro che succede se durante l'esecuzione del processo PRODUTTORE dopo aver eseguito l'istruzione wait lo scheduler decide che è il turno del processo CONSUMATORE?

Se ho capito bene (e non ne sono certo):

allora nel processo PRODUTTORE è stato prodotto il messaggio da inserire nel buffer poi è stata eseguita la primitiva wait che ha decrementato a 0 il semaforo spazio_disponibile, avviene il cambio di contesto e viene caricato nella CPU il processo consumatore che si trova il semaforo messaggio_disponibile settato a 0 per cui sospende tale processo e mette il suo descrittore nella coda dei processi sospesi relativa a tale semaforo...il processo è sospeso e la sua sezione critica di prelevamento dal buffer impedita. A questo punto il sistema operativo prevede ad un nuovo cambio di contesto a favore del processo PRODUTTORE che riprende da dove era rimasto ovvero inizia l'esecuzione della sua sezione critica in cui deposita il messaggio poi eseguirà la signal che incrementa il semaforo messaggio disponibile e così quando verrà caricato il processo CONSUMATORE potrà eventualmente eseguire la sua sezione critica...

Funzionano grossomodo così sti benedetti semafori o non c'ho capito un ceppotto? :eek: :cry:

Grazie
Andrea

Slayer86
28-05-2007, 19:06
Ciao,
stò studiando sistemi operativi (non sò se è meglio chiedere quì o nel 3d di informatica in scienza e tecnica...)

Stò vedendo la sezione del problema della mutua esclusione di una risorsa da parte di 2 o più processi che vi vorrebbero provare ad accedere in particolare il caso del modello PRODUTTORE-CONSUMATORE (con buffer di capacità unaria).

In pratica ho un processo PRODUTTORE che produce un messaggio da inserire nel buffer (di dimensione 1) ed un processo CONSUMATORE che deve estrarre il messaggio dal buffer ed usarlo per qualche suo scopo.

Quindi i vincoli sono che il PRODUTTORE non può inserire nulla nel buffer se questo è pieno ed il CONSUMATORE non può estrarre nulla dal buffer se questo è vuoto quindi devo risolvere un problema di sincronizzazione dei due processi mediante l'uso DI 2 semafori (in questo caso semafori binari) usando le rispettive primitive: wait e signal.

Quindi avrei una cosa del genere in pseudocodice:


Processo PRODUTTORE{
do{
<PRODUZIONE DEL NUOVO MESSAGGIO>;
wait(spazio_disponibile);
<DEPOSITO DEL MESSAGGIO NEL BUFFER>;
signal(messaggio_disponibile);
}while(!fine);
}

Processo CONSUMATORE{
do{
wait(messaggio_disponibile);
<PRELIEVO DEL MESSAGGIO DAL BUFFER>;
signal(spazio_disponibile);
<CONSUMO DEL MESSAGGIO>
}while(!fine);
}


Facendo l'ipotesir che il buffer è inizialmente vuoto bisogna settare i 2 valori dei semafori:
messaggio_disponibile a 0 e spazio_disponibile ad 1

In pratica il PRODUTTORE per prima cosa produce il messaggio da mettere nel buffer poi tramite la wait verifica se il valore numerico di spazio disponibile che sarà uguale ad 1 che tramite la wait viene dcrementato di 1 e viene eseguita la sezione critica di deposito del messaggio e successivamente viene resa disponibile tramite la signal la risorsa al processo consumatore che potrà estrarre dal buffer.

Ora visto che i 2 processi possono sovrapporsi nel tempo tra loro che succede se durante l'esecuzione del processo PRODUTTORE dopo aver eseguito l'istruzione wait lo scheduler decide che è il turno del processo CONSUMATORE?

Se ho capito bene (e non ne sono certo):

allora nel processo PRODUTTORE è stato prodotto il messaggio da inserire nel buffer poi è stata eseguita la primitiva wait che ha decrementato a 0 il semaforo spazio_disponibile, avviene il cambio di contesto e viene caricato nella CPU il processo consumatore che si trova il semaforo messaggio_disponibile settato a 0 per cui sospende tale processo e mette il suo descrittore nella coda dei processi sospesi relativa a tale semaforo...il processo è sospeso e la sua sezione critica di prelevamento dal buffer impedita. A questo punto il sistema operativo prevede ad un nuovo cambio di contesto a favore del processo PRODUTTORE che riprende da dove era rimasto ovvero inizia l'esecuzione della sua sezione critica in cui deposita il messaggio poi eseguirà la signal che incrementa il semaforo messaggio disponibile e così quando verrà caricato il processo CONSUMATORE potrà eventualmente eseguire la sua sezione critica...

Funzionano grossomodo così sti benedetti semafori o non c'ho capito un ceppotto? :eek: :cry:

Grazie
Andrea

Ciao ho passato il mese scorso l'esame di sistemi operativi ad ingegneria devo dire che la parte riguardante la concorrenza è stata veramente tostissima e soprattutto spesso si crede di aver considerato ogni possibilità per poi trovarsi difronte ad un bel dead-lock :D... dopo quasto incoraggiamento ti rispondo... allora mi pare da ciò che hai scritto che hai capito il funzionamento dei semafori... in bocca al lupo per l'esame...

D4rkAng3l
28-05-2007, 19:37
Ciao ho passato il mese scorso l'esame di sistemi operativi ad ingegneria devo dire che la parte riguardante la concorrenza è stata veramente tostissima e soprattutto spesso si crede di aver considerato ogni possibilità per poi trovarsi difronte ad un bel dead-lock :D... dopo quasto incoraggiamento ti rispondo... allora mi pare da ciò che hai scritto che hai capito il funzionamento dei semafori... in bocca al lupo per l'esame...

TNX si la concorrenza è un casotto...poi da quello che ho visto oltre alla concorrenza tra processi puoi avere anche quella tra thread che comporta un po' di differenze... :cry:
L'esame lo ho tra 10 giorni...ora stò vedendo l'invio di messaggi tra processi...poi mi tocca un altro centinaio di pagine di teoria sulla gestione della memoria I/O etcetc...c'è qualche esercizio pratico ma è più teoria che altro...e una parte sui filesystem e qualcosa di pratico su linux e win...spero di arrivare all'esame con almeno l'80% del programma fatto quantomeno dignitosamente...in 4 giorni sono riuscito a capire benino una 90ina di pagine m la parte più tosta è questa sulla concorrenza che mi stà portando via molto tempo...tipo oggi in 4 ore avrò studiato 13 pagine :cry: :cry: :cry: :cry:

casacup
09-07-2008, 14:38
(fin da ora vi chiedo scusa per le lettere accentate, ma sto su una tastiera con un layout degli anni 50).

Provo a postare qui, accodandomi alla discussione: sto sbattendo la capoccia sui semafori e su tutti gli annessi e connessi. Ma prima di andare al problemi dei filosofi, del tabaccaio e compagnia vorrei capire per bene la base.

Per quanto abbia capito quale sia il funzionamento dei semafori (se la risorsa e libera, ovvero semaforo verde, occupala, metti il semaforo a rosso, usala, e poi rimettilo a verde) non capisco il funzionamento delle primitive signal e wait.

Ecco il codice che ho con me (molto generico naturalmente)




typedef struct {
int valore;
struct processo *L:
} semaforo


void wait(semaforo S) {
S.valore--;
if (S.valore < 0) {
aggiungi questo processo a S.L;
block():
}
}


void signal(semaforo S) {
S.valore++;
if (S.valore <= 0) {
togli un processo P da S.L;
wakeup(P):
}
}





(scusate la mancata indentazione ma fancendo il copia incolla se ne e andata all'aceto...).

Alcune precisazioni:
- non ho la struct processo, naturalmente e un array ma non so niente altro
- block sospende il processo che la invoca e lo mette nello stato di attesa (presumibilmente dovrebbe anche aggiungerlo ad S.L)
- wakeup(P) e una chiamata di sistema che mette in pronto il processo P bloccato (e quindi lo dovrebbe togliere da S.L)

Sono molte le cose che non mi sono chiare, ed alcune domande sembreranno sicuramente senza senso dato che non ho al momento una visione globale della cosa.


1) essere aggiunti o tolti da S.L cosa implica? semplicemente che si e in attesa di usare la risorsa (se si e dentro a S.L)?
2) la struttura generale dovrebbe essere
wait(semaforo)
esecuzione sezione critica
signal(semaforo)
considerando quello che fanno le due primitive dovrebbe essere una cosa del tipo: analizza se la risorsa e liber, se lo e metti il semaforo a rosso, usala in maniera esclusiva, poi liberala e rimette il semaforo a verde, se invece e piena mettiti in attesa in S.L. (fino qui ok).
Cio che pero non mi torna e cosa succede a livello di codice: supponiamo di avere due casi, nel primo il semaoforo parte da 1, nel secondo da 0 (caso di un semaforo binario).

semaforo a 1 -> eseguiamo il wait -> semaforo a 0 -> non blocchiamo niente, eseguiamo il pezzo critico -> eseguiamo la signal -> semaforo torna a 1 -> nessun problema
(e fino qui niente di male, la prima volta che si esegue un processo nel programma semaforo e inizializzato ad 1 quindi non abbiamo problema)

semaforo a 0 -> eseguiamo il wait -> semaforo a -1 -> il processo finisce in S.L (viene attivato il block) -> e poi che diamine succede?
in teoria il processo in questione (chiamiamolo Q) verra richiamato da una wakeup: una volta eseguita la wakeup pero il processo cosa dovra fare, il wait o il signal?
ed inoltre in quale caso si verifica l'if del signal? avremo S.valore <= a zero se e solo se, prima dell'incremento, era un numero negativo (supponiamo -1 che incrementato fa zero). Non riesco ne a capire quando questa cosa si verifichi (la signal non dovrebbe essere fatta per liberare la risorsa? e allora il semaforo come fa a stare a 0 dopo l'esecuzione della parte critica? in teoria non sto piu accedendo ai dati condivisi) ne perche un processo bloccato venga chiamato solo in questo caso (per la stessa identica motivazione).


Scusate il post lungo e noioso, ma ho cercato parecchio su internet e non mi sono chiarito nulla dato che in cio che ho letto si parte subito sparati con i semafori applicati a varie situazioni.

grazie a chiunque mi aiutera, e scusate ancora per gli accenti :)