Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


Exercicis Concurrencia, Ejercicios de Sistemas Operativos

Asignatura: Sistemes operatius, Profesor: Maria Bosch, Carrera: Enginyeria Informàtica, Universidad: UPC

Tipo: Ejercicios

2010/2011

Subido el 14/11/2011

elanor-12
elanor-12 🇪🇸

4.3

(12)

15 documentos

1 / 13

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
SolProbConcTardor09 1 02/12/2009
Solucions a problemes de concurrència/ tardor2009
Problema del barber adormit
Procés barber
espera (afaitar)
aten_client
senyal (afaitat)
fprocés
Procés client
i
espera (mutex)
si (cadires > 0)
llavors cadires --
senyal (mutex)
senyal (afaitar)
espera (afaitat)
espera (mutex)
cadires ++
senyal (mutex)
sino senyal (mutex)
destruir_procés
fsi
fiprocés
Varglobals:
cadires = 7; afaitar: semàfor
mutex, afaitat: semàfor binari
init (afaitar,0); init (afaitat, 0); init (mutex,1)
1
ll barber, client
i
1. Volem simular el comportament d’un menjador universitari self-service, mitjançant un procés
composat per varis fluxes, i utilitzant semàfors com a eina per a solucionar els problemes de
concurrència que poden aparèixer.
Disposem de tres tipus de fluxes (client, cuiner, safataire) que executaran el següent codi:
void client()
{
agafar_safata_neta; /* s’espera fins obtenir una safata neta
escollir_menjar(); /* s’espera fins obtenir menjar
escollir_lloc(); /* s’espera fins obtenir lloc buit
menjar();
alliberar_lloc;
retornar_safat_bruta;
}
void cuiner()
{
While (!fi) {
Servir_menjar();
...
}
}
void safataire()
{
while (!fi) {
agafar_safata_bruta (); /*s’espera fins obtenir safata
netejar_safata();
retornar_safata_neta();
}
}
pf3
pf4
pf5
pf8
pf9
pfa
pfd

Vista previa parcial del texto

¡Descarga Exercicis Concurrencia y más Ejercicios en PDF de Sistemas Operativos solo en Docsity!

SolProbConcTardor09 1 02/12/

Solucions a problemes de concurrència/ tardor

Problema del barber adormit

Procés barber espera (afaitar) aten_client senyal (afaitat) fprocés

Procés client (^) i espera (mutex) si (cadires > 0) llavors cadires -- senyal (mutex) senyal (afaitar) espera (afaitat) espera (mutex) cadires ++ senyal (mutex) sino senyal (mutex) destruir_procés fsi fiprocés

Varglobals: cadires = 7; afaitar: semàfor mutex, afaitat: semàfor binari init (afaitar,0); init (afaitat, 0); init (mutex,1)

1

ll barber, client (^) i

  1. Volem simular el comportament d’un menjador universitari self-service, mitjançant un procés composat per varis fluxes, i utilitzant semàfors com a eina per a solucionar els problemes de concurrència que poden aparèixer.

Disposem de tres tipus de fluxes (client, cuiner, safataire) que executaran el següent codi:

void client ()

{ agafar_safata_neta; /* s’espera fins obtenir una safata neta escollir_menjar(); /* s’espera fins obtenir menjar escollir_lloc(); /* s’espera fins obtenir lloc buit menjar(); alliberar_lloc; retornar_safat_bruta; }

void cuiner () { While (!fi) { Servir_menjar(); ... } } void safataire () { while (!fi) { agafar_safata_bruta (); /*s’espera fins obtenir safata netejar_safata(); retornar_safata_neta(); } }

SolProbConcTardor09 2 02/12/

Respon a les següents preguntes. Allà on hagis d’implementar codi, indica si les variables són locals o globals, la seva inicialització, i justifica la resposta

a) Suposant que la capacitat del restaurant és de N LLOCS posicions, implementa les rutines escullir_lloc() i alliberar_lloc(). Observa que la rutina escollir_lloc ha de retornar el control quan hi hagi algún lloc lliure però no cal que indiqui quin.

Es pot resoldre amb un semàfor inicialitzat al nombre de llocs

Disponibles, inicialment ( LLOCS ); el comptador d’aquest semàfor representa el nombre de

llocs disponibles. Escollir un lloc serà fer un espera (decrementa el comptador i en cas que

ja valgués 0, bloqueja el fluxe). Alliberar lloc serà fer un senyal sobre el mateix semàfor

(incrementa el comptador i,en cas que hi hagi algún fluxe a la cua bloquejat senzillament

desbloqueja el primer). El semàfor ha de ser global ja que l’utilitzaran varis fluxes.

init (lloc, LLOCS); void escollir_lloc() { espera(lloc) ; } void alliberar_lloc() { senyal(lloc) ; }

b) Implementa les rutines agafar_safata_neta(), retornar_safata_bruta(), agafar_safata_bruta(), retornar_safata_neta(). Pots suposar que inicialment hi ha NETES safates netes i BRUTES safates brutes.

Es pot resoldre amb un parell de semàfors, un per a representar el nombre se safates

netes i un altre per a representar les brutes.Tots dos han de ser globals.

init (n, NETES); init (b, BRUTES);

void agafar_safata_neta() { espera(n); } void agafar_safata_bruta() { espera(b); } void retornar_safata_neta() { senyal(n); } void retornar_safata_bruta() { senyal(b); }

c) En un moment donat és necessàri afegir N safates netes addicionals. Tenint en compte el que has indicat en l’apartat anterior, implementa la rutina afegir_safates (int N) per fer aquesta tasca.

SolProbConcTardor09 4 02/12/

inicialitzacions (); while (1) { espera(s1) obtenir_petició (pet); crear_fluxe tractar_petició (pet); } }

void tractar_petició (petició pet) { /tractament d’una petició/ ... espera (mutex) #pet ++ senyal (mutex) senyal(s1) fi_fluxe; }

c) El servidor disposa d’un nombre màxim de fitxers temporals per a realitzar la seva tasca MAX_TEMP i les peticions (pet) contenen un camp (temporals) que indica quants fitxers temporals són necessàris per a atendre la petició, se suposa que temporals sempre serà més petit que TEMP_MAX. A la rutina tractar_petició tenim el següent codi, on tempor és una variable de tipus semàfor inicialitzat a MAX_TEMP. Pot donar algún tipus de problema aquest codi? justifica-ho. En cas afirmatiu proposa una solució.

Aquest codi pot presentar deadlock. Per exemple, si tenim 2 fitxerstemporals i 2 peticions en

necessiten també 2 cadacuna, pot passar que les dues peticions agafin un temporal i es

bloquegin pel segon, produint-se les 4 condicions necessàries per a l’existència de deadlock.

Solució: protegir el bucle for amb una espera sobre un semàfor per a evitar que dues

peticions diferents estiguin competin simultaniament per fitxers temporals

Al main() mutex2: semàfor; init ( mutex2,1);

void *tractar_petició (petició pet) { int i; espera (mutex2); for (i=0; i < pet.temporals; i++) espera (tempor); senyal (mutex2); / tractament d’una petició */ for (i=0; i < pet.temporals; i++) senyal (tempor); }

  1. S’ha instalat un nou servei de rentaduria que funciona de la següent manera: quan un client entra a la rentaduria, insereix monedes en una de les moltes estacions de reserva i selecciona la quantitat de rentadores que necessitarà.. L’estació de reserva li assigna rentadores lliures retornat- li unes fitxes que identifiquen cada rentadora. A continuació el client insereix les fitxes en les rentadores indicades i renta la roba. Un cop acabat el cicle, les rentadores estaràn lliures altre cop.

Tant les estacions de reserva com les rentadores estàn connectades a un ordinador central. L’ordinador central manté dues variables per al control del sistema:

init (s1,MAXPETICIONS) init (mutex,1) #pet =

Com que varies peticions poden acabar simultaniament, cal accedir a la variable pet en exclusió mútua

SolProbConcTardor09 5 02/12/

  • Un vector de booleans declarat com a disponible[NRENTADORA] que indica si una rentadora està lliure o no (NRENTADORA és el nombre total de rentadores que hi ha a la rentaduría). Inicialment està tot a CERT.
  • Un semàfor anomenat nlliures inicialitzat a NRENTADORA que indica quantes rentadores hi ha lliures.

A continuació és mostra el codi actualment implementat en l’ordinador central per a obtenir les rentadores i per alliberar-les:

void obtenir_rentadora(int nrent) { int i,j ; for (i=0; i<nrent; i++){ wait(nlliures); j = 0; while ((disponible[j] == false && (j<NRENTADORA)) j++ ; if (j==NRENTADORA) error(“FATAL ERROR”); else disponible[j] = false; } }

void allibera_rentadora (int rent) { signal (nlliures) ; disponible[rent] = true ; }

Després d’unes setmanes de funcionament han aparegut dos tipus de problemes : a) A vegades una estació de reserva dóna « FATAL ERROR » i no hi ha més remei que reinicialitzar el sistema b) Sembla que, de tant en tant, a dos clients diferents se’ls assigna la mateixa rentadora al mateix temps Es demana resoldre aquests problemes explicant per qué passa cadascun d’ells i modificant el codi per a resoldre-ho.

a) Això passa perquè en alliberar_rentadora fem el senyal(nlliures) abans de dir quines

rentadores estàn lliures. Si hi hagués un canvi de context entre aquestes dues instruccions,

és possible que en obtenir_rentadores no ens blouegi el espera(nlliures), però

com que la variable disponible està encara a FALSE per a aquesta rentadora en particular,

el bucle while acabi perquè j ha arribat a NRENTADORA sense trobar-ne cap a TRUE. La

proposta de solució esta en invertir l’ordre de les dues instruccions que conformen la rutina

allibera_rentadora :

void allibera_rentadora (int rent) { disponible[rent] = true ; signal (nlliures) ; }

b) El problema es dóna perquè no hi ha protecció en la consulta i modificació de la variable

global disponible , així doncs, si hi ha un canvi de context i dos clients alhora volen

reservar rentadora, és possible que dues estacions de reserva vegin la condició

disponible[j] == false i per tant assignin la mateixa rentadora als dos clients. La

proposta de solució és implementar tota la rutina obtenir_rentadora en Exclusió mútua.

Caldrà afegir a l’acció principal un semàfor binari inicialitzat a 1 ( mutex ).

SolProbConcTardor09 7 02/12/

void client () {

anar_a_la_orxateria (); sema_wait (&sem4); sema_wait (&sem5); n_orxates = quantes_orxates () ; sema_signal (&sem5); sema_signal (&sem2); sema_wait (&sem3); sema_signal (&sem4); prendre_orxates (); }

void orxater () { int preparade s = 0; while (TRUE) { preparar_orxata () ; sema_signal (&sem1); sema_wait (&sem6); preparades ++ ; sema_signal (&sem6); } }

  1. Amb quins valors inicialitzaries cadascun dels semàfors?

semàfor inicialitzat serveix per

sem1 0 Sincronitza l’orxater i el cambrer

Cada cop que l’orxater hagi acabat de preparar una orxata farà un signal sobre sem1, i el

cambrer la consumirà fent un wait.

sem2 0 Sincronitza el cambrer amb el client

Quan el client hagi escrit la seva petició, farà un signal sobre el semàfor per avisar al cambrer

que la serveixi.

sem3 0 Sincronitza el client amb el cambrer

Quant totes les orxates demanades estiguin servides, el cambrer farà un signal sobre el semàfor

i el client podrà continuar executant.

sem4 1 Exclusió mútua

Garanteix que no hi pugui haver varis clients alhora fent peticions al cambrer

sem5 1 Exclusió mútua

Garanteix l’accés a la variable quantes_orxates en exclusió mútua

sem6 1 Exclusió mútua

Regula l’accés a la variable preparades

  1. Per a què es suposa que serveixen els semàfors sem5 i sem6? Són realment necessaris? perquè?

Aquests dos semàfors serveixen per implementar exclusions mútues.

sem5 no és necessari. Gràcies a sem2 i sem4 no es pot donar el cas de que en el mateix

moment varis fluxes accedeixin a n_orxates

sem6 no és necessari ja que controla una exclusió mútua sobre una variable preparades no

compartida

  1. Quina informació es guarda de manera implícita al compatdor del semàfor sem1?

El comptador de sem1 indica el nombre d’orxates ja preparades i encara no servides. L’orxater

l’incrementa cada vegada que en té una de preparada i el cambrer el decrementa cada vegada

que en consumeix una

  1. Per a què serveix el semàfor sem4?

sem4 serveix per implementar una exclusió mútua entre els clients. Fins que un no és servit, cap

altre no pot indicar al cambrer que espera.

SolProbConcTardor09 8 02/12/

  1. S’està estudiant la possibilitat de fer un parking al campus de l’Escola, amb una capacitat d’ N

cotxes. Es vol simular el funcionament d’aquest parking mitjançant dues rutines entrar_parking,

sortir_parking que s’executen concurrentment i es sicronitzen mitjançant semàfors. El

funcionament serà el següent: Quan un cotxe vol entrar al parking, farà una crida

entrar_parking(). Si el parking està plè (N cotxes), el cotxe es bloquejarà a una cua d’espera

fins que hi hagi lloc perquè ha sortit algún cotxe. Per sortir del parking, els cotxes faràn una crida

sortir_parking(). Si a la cua hi ha algún cotxe esperant, aquesta funció permetrà que entri al

parking.

Es proposa la següent solució d’implementació de la part més significativa de les funcions:

entrar_parking()

espera (mutex)

si (cotxes = N)

llavors cua++

senyal (mutex)

espera (esp)

sino cotxes++

senyal (mutex)

fsi

sortir_parking()

espera (mutex)

si (cua > 0)

llavors senyal (esp)

cua— ()*

sino cotxes—

fsi

senyal (mutex)

Es demana respondre a les següent qüestions tot justificant breument les respostes.

  1. Còm s’inicialitzen i de quin tipus són les variables i semàfors en el programa principal? Quina utilitat tenen?
  2. Es proposa la següent modificació:

entrar_parking()

espera (mutex)

si (cotxes = N)

llavors cua++

espera (esp)

sino cotxes++

fsi

senyal (mutex)

Et sembla correcte? Perquè?

  1. És necessària la variable cua? Podriem substituïr-la pel semàfor esp?
  2. Simula el funcionament del parking en la següent situació: N=3. A l’inici parking buit. Arriben 5 cotxes seguits i posteriorment en surt un. Quin valor prendran les variables i semàfors al final de la seqüència? Un alumne discuteix amb una companya la validesa de la solució proposada i justifica el seu raonament perqué troba a faltar l’instrucció cotxes— en el punt marcat per ()*. Hi estàs d’acord? Perquè?

SolProbConcTardor

10

02/12/

Volem conèixer la densitat del trànsit en un cert punt de l’autopista. El sistema de mesura que s’utilitzaconsisteix en dos sensors, un per cadascun dels sentits. Aquests sensors capten cada cert temps laquantitat de vehicles que han passat en un determinat sentit.Dissenyeu un programa amb tres accions concurrents; dues d’elles executaran el mateix codi, queconsistirà en llegir el sensor, cadascuna el seu, i emmagatzemar el valor llegit. L’altre mostrarà perpantalla, la quantitat de cotxes que han passat en cada sentit i la mitjana de la via. Es propasa elsegüent codi com a punt de partida de la solució.a) Afegiu les primitives de semàfors per a sincronitzar les accions i que les dades mostrades perpantalla siguin coherents i la mitjana es calculi només quan hagin arribat noves dades en els dossentits. És important que la solución tingui el màxim de paral·lelisme, és a dir, que les exclusionsmútues siguin mínimes. Algorisme

Tràfec

var tràfec : taula [1..2] de enter

sincro : semàfor

/*sincro lectors/escriptors

mutex : taula [1..2] de semàfor /*E.M. tràfec

fvar init (mutex [1],1); init (mutex [2], 1); init (sincro,0); Lector[1] || Lector[2] || Escriptor FalgorismeAcció

Lector ( sentit: enter)

var dada : enter fvarRepetir

dada := llegir_sensor(sentit) espera (mutex[sentit]) tràfec [sentit] := dada senyal (sincro) Finsque fals

Acció

Escriptor

var mitjana: enter fvarRepetir

espera (sincro)espera (sincro) mostra_a_pantalla ( tràfec[1] )mostra_a_pantalla ( tràfec[2] )mitjana:=sencer((tràfec[1]+ tràfec[2]) / 2) senyal (mutex [1])senyal (mutex [2]) mostra_a_pantalla (mitjana) finsque falsFacció

SolProbConcTardor

11

02/12/

b)

El mateix que l’anterior però amb pas de missatges

Algorisme

Tràfec-missatges

var tràfec : taula [1..2] de enter

sincro : bústia

/*sincro lectors/escriptors

mutex : taula [1..2] de bústia /*E.M. tràfec

fvar envia (mutex [1],mssg); envia (mutex [2], mssg); Lector[1] || Lector[2] || Escriptor FalgorismeAcció

Lector ( sentit: enter)

var dada : enter fvarRepetir

dada := llegir_sensor(sentit) rep (mutex[sentit], mssg) tràfec [sentit] := dada envía (sincro,mssg) Finsque fals

Acció

Escriptor

var mitjana: enter fvarRepetir

rep (sincro)rep (sincro) mostra_a_pantalla ( tràfec[1] )mostra_a_pantalla ( tràfec[2] )mitjana:=sencer((tràfec[1]+ tràfec[2]) / 2) envia (mutex [1])envía (mutex [2]) mostra_a_pantalla (mitjana) finsque falsFacció

SolProbConcTardor

13

02/12/

Solució amb pas de missatges (esquemàtic) A1:

B1,C1,D1:

{^

rep (N, mssg)

{^

crear_?

rep (N, mssg)

envia (N mssg)

rep (N, mssg)

crear_A } A2:

B2,C2,D2:

{^

rep (M mssg)

{^

opció (&mssg)

envia (M, mssg)

{^

cas B2 : crear_B

cas C2 : crear_C3cas D2 : crear_D

Capacitat de la bústia M^ 0 : El primer procés que acabi, envía el missatge, el procés emisor podrà continuar quan A2 hagi llegit el missatge, però el 2on i 3erprocessos quedaran bloquejats indefinidament, esperant que A2 llegeixi el missatge però això no passarà mai perqué A2 ja ha finalitzat.1 : El primer procés que acabi, envía el missatge, el procés emisor

i el 2on procés podran continuar quan A2 hagi llegit el missatge,

però el 3er procés quedarà bloquejat indefinidament, esperant que A2 llegeixi el missatge però això no passarà mai perqué A2 ja hafinalitzat.Conclusió!! M ha de ser de capacitat 2