- Tomar una foto a los pasos 4 y 5 como se muestra en el ejemplo
- Ponerlas en formato pdf
- Enviarlas al correo electronico: sistemas.operativos.fime@gmail.com
- Asunto: HORA - Tarea 4 - Matricula - Nombre
- Entregarla antes del jueves 23 de mayo
1.- Implementar Locks en NachOS
Bueno lo primero que tenemos que hacer es abrir nuestra terminal y ir a nuestra carpeta de threads
cd nachos/nachos/code/threads
Bueno para la implementación de los Locks editaremos los archivos synch.cc y synch.h.
sudo gedit synch.h
Buscamos la linea 89 y depues de donde dice:
private: const char* name; // para depuraci�nAgregaremos Semaphore semaforo;
private: const char* name; // para depuraci�n Semaphore semaforo;
Ahora editaremos el synch.cc
sudo gedit synch.ccAl principio agregamos:
#include <iostream>
Buscamos donde viene Locks debe verse algo asi
// Dummy functions -- so we can compile our later assignments // Note -- without a correct implementation of Condition::Wait(), // the test case in the network assignment won't work! Lock::Lock(const char* debugName) {} Lock::~Lock() {} void Lock::Acquire() {} void Lock::Release() {}
Una vez que implementamos los Locks deberia verse asi:
Lock::Lock(const char* debugName) :name(debugName), semaforo("semaforo_lock", 1) //constructor { printf("lock constructor\n"); } Lock::~Lock() { printf("lock destructor \n");//destructor } void Lock::Acquire() { semaforo.P(); printf("acquiring lock\n"); //debugging purposes } void Lock::Release() { semaforo.V(); printf("releasing lock\n"); //debugging purposes }

2.- Crear un programa que corra Locks
Bueno para esto abriremos el archivo threadtest.cc.
sudo gedit threadtest.ccLo primero que tenemos que agregar son las librerias nuevas
#include "synch.h" //agregado para ejecutar los locks #include <iostream> using namespace std; #include <ctime> #include <cstdlib>
Ahora antes de:
void SimpleThread(void* name) { // Reinterpret arg "name" as a string char* threadName = (char*)name; // If the lines dealing with interrupts are commented, // the code will behave incorrectly, because // printf execution may cause race conditions. for (int num = 0; num < 10; num++) { //IntStatus oldLevel = interrupt->SetLevel(IntOff); printf("*** thread %s looped %d times\n", threadName, num); //interrupt->SetLevel(oldLevel); //currentThread->Yield(); } //IntStatus oldLevel = interrupt->SetLevel(IntOff); printf(">>> Thread %s has finished\n", threadName); //interrupt->SetLevel(oldLevel); }
Agregaremos los Siguientes codigos:
Codigo del Productor Consumidor
//apuntador a un lock compartido en todo el codigo Lock *l; Lock *l2; //lock usado para crear un deadlock Lock *l3; //lock usado para crear un deadlock Lock *consumidor; //usado para bloquear a los consumidores Lock *productor; //usado para bloquear a los productores Lock *modificarComestibles; //exclusion mutua entre productores y consumidores int comestibles; int maxComestibles; //se ejecuta la rutina para los consumidores void Consumidor(void *name){ char* threadName = (char*)name; bool tieneLock = false; while(1){ if(!tieneLock){ consumidor->Acquire(); tieneLock = true; } cout <<"comestibles: "<<comestibles << "\n"; if(comestibles > 0){ //podemos consumir productos //parte critica del codigo que se comparte entre todos los threads //sean productores o consumidores modificarComestibles->Acquire(); comestibles --; modificarComestibles->Release(); cout<<threadName<<" consumio\n"; consumidor->Release(); tieneLock = false; }else{ cout <<threadName <<" no puede consumir \n"; } currentThread->Yield(); } } //se ejecuta la rutina para los productores void Productor(void* name){ char* threadName = (char*)name; //cout <<"\nrutina del productor\n"; bool tieneLock = false; while(1){ if(!tieneLock){ productor->Acquire(); tieneLock = true; } cout <<"comestibles: "<<comestibles << "\n"; if(comestibles < maxComestibles){ //podemos producir //parte critica del codigo que se comparte entre todos los threads //sean productores o consumidores modificarComestibles -> Acquire(); comestibles ++; modificarComestibles -> Release(); cout<<threadName<<" produjo\n"; productor->Release(); tieneLock = false; }else{ cout <<threadName <<" no puede producir \n"; } currentThread->Yield(); } }
Prueba Fairness.
void PruebaFairness(void* name){ //parseando de tipo void a tipo char char* threadName = (char*)name; cout << "ejecutando Fairness para thread "<< threadName << "\n"; int repeticiones = 3; while(repeticiones >= 0 ){ cout << threadName <<" quiere el lock\n"; l->Acquire(); cout << threadName <<" tiene el lock\n"; l->Release(); repeticiones--; currentThread->Yield(); //despierta el primer thread en la cola // currentThread->Sleep();//manda el thread al final de la cola } }Prueba Liveness.
void PruebaLiveness(void* name){ char* threadName = (char*)name; srand(time(0)); float probabilidad; float pasa = 0.5; int a; int repeticiones = 0; while(repeticiones < 3){ probabilidad = (float)rand()/RAND_MAX ; if (probabilidad > pasa){ cout << threadName << " pide el lock\n"; l->Acquire(); cout << threadName << " tiene el lock\n"; for (int i = 0; i< 10000; i++){ a++; } for (int i = 0; i< 10000; i++){ a--; } l->Release(); cout << threadName << " libera el lock\n"; //cout << probabilidad<<endl; } currentThread->Yield(); repeticiones++; } }
Prueba Safety (con esta aremos un deadlock).
void DeadLock1(void* name){ char* threadName = (char*)name; cout <<"\n"<<threadName <<" funciona de la siguiente manera\n"; cout <<"l2 Acquire()\n"; cout <<"l3 Acquire()\n"; cout <<"realiza operaciones criticas \n"; cout <<"l3 release()\n"; cout <<"l2 release()\n"; currentThread->Yield(); l2->Acquire(); cout <<"\n"<<threadName<<" Adquiere l2\n"; cout <<threadName<<" es interrumpido\n"; currentThread->Yield(); l3->Acquire(); cout<<"esta parte nunca va a pasar\n"; l3->Release(); l2->Release(); } void DeadLock2(void* name){ char* threadName = (char*)name; cout <<"\n"<<threadName <<" funciona de la siguiente manera\n"; cout <<"l3 Acquire()\n"; cout <<"l2 Acquire()\n"; cout <<"realiza operaciones criticas \n"; cout <<"l2 release()\n"; cout <<"l3 release()\n"; currentThread->Yield(); l3->Acquire(); cout <<"\n"<<threadName<<" Adquiere l3\n"; cout <<threadName<<" es interrumpido\n"; currentThread->Yield(); l2->Acquire(); cout<<"esta parte nunca va a pasar\n"; l2->Release(); l3->Release(); }
Despues de Agregarlos buscamos el que dice ThreadTest() y en este agregaremos /* y */ para que no ejecute el SimpleTest(), debe quedar como en la siguiente imagen.
Despues del */ y antes de } agregamos el siguiente codigo:
int n = 10; int p = 3; //cuantos productores int c = 2;// cuantos consumidores l = new Lock("lock1"); l2 = new Lock("lock2"); l3 = new Lock("lock3"); modificarComestibles = new Lock("comestibles");//bloquea productores y consumidores consumidor = new Lock("consumidor");//bloquea consumidores productor = new Lock("productor");//bloquea productores comestibles = 0; //cero comestibles maxComestibles = 10; //maximo de productos que podemos tener en cola cout << "*------------->Ejecutando prueba para Fairness<-------------*\n"; for ( int k=1; k<=n; k++) { char* threadname = new char[100]; sprintf(threadname, "Hilo %d", k); Thread* newThread = new Thread (threadname); newThread->Fork (PruebaFairness, (void*)threadname); } PruebaFairness( (void*)"Hilo 0"); //se realiza la prueba de livenes "si varios threads piden un lock //al mismo tiempo al menos uno lo debe de obtener" cout << "\n*------------->Ejecutando prueba para Liveness<-------------*\n"; for ( int k=1; k<=n; k++) { char* threadname = new char[100]; sprintf(threadname, "Hilo %d", k); Thread* newThread = new Thread (threadname); newThread->Fork (PruebaLiveness, (void*)threadname); } PruebaLiveness((void*)"Hilo 0"); // Productor((void*)"Productor0"); /* cout << "\n*------------->Ejecutando prueba para Safety<-------------*\n"; for ( int k=1; k<=1; k++) { char* threadname = new char[100]; sprintf(threadname, "Hilo %d", k); Thread* newThread = new Thread (threadname); newThread->Fork (DeadLock2, (void*)threadname); } DeadLock1((void*)"Hilo 0"); */ cout <<"\n*------------->Ejecutando el programa del productor consumidor<-------------*\n"; cout << "\ncreando productores\n"; for ( int k=1; k<=p; k++) { char* threadname = new char[100]; sprintf(threadname, "Productor %d", k); Thread* newThread = new Thread (threadname); newThread->Fork (Productor, (void*)threadname); } cout << "\ncreando consumidores\n"; for ( int k=2; k<=c; k++) { char* threadname = new char[100]; sprintf(threadname, "Consumidor %d", k); Thread* newThread = new Thread (threadname); newThread->Fork (Consumidor, (void*)threadname); } Consumidor((void*)"Consumidor 1");
3.- Compilar
Bueno aqui tecleamos en la terminal lo siguiente:
cd ..
Y ahora si le damos make.
make4.- Primera prueba correr nachOS.
Suponiedo que no marco algun error volvemos a la carpeta de threads y para correrlo le tecleamos:
cd threads
y lo corremos
./nachos
Esta prueba deberia correr PruebaFairness, PruebaLiveness y el Consumidor - Productor. La ejecución deberia verse de la siguiente manera:
5.- Causar un DeadLock.
Para matar el proceseso presionamos Ctrl C, y despues abrimos el archivo threadtest.cc y borraremos el /* y */ del DeadLock como en la siguiente imagen:
Ahora lo siguiente es volver a compilar nachOS, tecleamos en la terminal lo siguiente:
Y ahora si le damos make.
Suponiedo que no marco algun error volvemos a la carpeta de threads y para correrlo le tecleamos:
Informacion y codigos de: http://sistemassoperativos.blogspot.mx/2011/09/first-practical-presentation.html
![]() |
Imagen para la tarea. |
5.- Causar un DeadLock.
Para matar el proceseso presionamos Ctrl C, y despues abrimos el archivo threadtest.cc y borraremos el /* y */ del DeadLock como en la siguiente imagen:
Ahora lo siguiente es volver a compilar nachOS, tecleamos en la terminal lo siguiente:
cd ..
Y ahora si le damos make.
make
Suponiedo que no marco algun error volvemos a la carpeta de threads y para correrlo le tecleamos:
cd threadsy lo corremos
./nachosUna vez que corremos nachOS deberia verse algo asi:
![]() | |
|
Informacion y codigos de: http://sistemassoperativos.blogspot.mx/2011/09/first-practical-presentation.html
No comments:
Post a Comment