Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Proceso
Ambiente de trabajo
Hilos y Procesos
Registros del CPU. Cambian de valor durante la ejecucin del programa
Contador de programa Puntero de pila Marco de pila (stack frame pointer) Otros (depende de cada CPU)
El S.O. lleva registro del contexto de cada proceso en una tabla llamada tabla de procesos
Hilos y Procesos
Memoria
Estos bloques de memoria contendrn tanto el cdigo como los datos del al proceso
Hilos y Procesos
Los sistemas operativos estn formados por
Hilos y Procesos
El ncleo es la parte central del S.O.
Crear procesos
Destruir procesos
Planificar la ejecucin de los procesos Ofrecer e implementar mecanismos de comunicacin entre procesos
Hilos y Procesos
Llamadas al sistema
Los procesos invocan al S.O. mediante llamadas al sistema (system calls) Una llamada al sistema es similar a una llamada a un procedimiento, pero el cdigo que se ejecuta no est en el programa, sino dentro del S.O. El sistema operativo y los programas de usuario se ejecutan en niveles diferentes desde el punto de vista del CPU La transicin de un nivel a otro consume ciclos de CPU: es mucho mas lenta una llamada al sistema que una llamada a un procedimiento dentro del mismo programa
Hilos y Procesos
Estados de los procesos
Ejecutndose. El proceso est usando la CPU Listo. No est en ejecucin pero no hay nada que lo impida. El proceso est esperando su turno para usar la CPU Bloqueado. No est en ejecucin. No puede ejecutarse mientras no ocurra cierto evento externo Posibles transiciones
1. 1.
Un proceso se bloquea para aceptar entrada de datos El planificador selecciona otro proceso para ejecutarlo El planificador selecciona este proceso para ejecutarlo Hay datos disponibles. El proceso se desbloquea
Hilos y Procesos
El planificador (scheduler)
Es la parte del ncleo que maneja las transiciones de estado de los procesos
Planificacin expropiativa (preemtive). Cuando el reloj del sistema genera una interrupcin, el planficador es invocado para que determine cual proceso se ejecutar a continuacin
Planificacin no expropiativa (non preemtive). Los procesos invocan al planificador
Hilos y Procesos
Algoritimos de planificacin
Round robin Planificacin por prioridad Combinacin de prioridad y round robin Otros
Hilos y Procesos
Hilos
Hilos y Procesos
Hilos
Hilos y Procesos
Tipos de hilos
Hilos manejados por el kernel Hilos manejados a nivel del usuario (green threads)
El sistema operativo conoce la existencia de los hilos. El planificador no selecciona procesos para ser ejecutados sino hilos. El hilo seleccionado puede pertenecer al mismo proceso o a un proceso diferente
Hilos y Procesos
Hilos manejados a nivel del usuario
El S.O. no conoce la existencia de los hilos Existe un nico hilo por proceso
Hilos y Procesos
Hilos del kernel Cambio de contexto Lento Al bloquearse un Bloqueos hilo el proceso no tiene que bloquearse Planificacin Expropiativa
Hilos y Procesos
Memoria compartida
Varios procesos pueden acceder a bloques de memoria compartida utilizando servicios del sistema Los hilos de un proceso pueden acceder a datos comunes
Hilos y Procesos
Cuando varios procesos tratan de acceder al mismo tiempo a los datos se presentan problemas de acceso simultno Ejemplo Que pasa si dos procesos tratan de acceder al un arreglo simultneamente?
Seccin crtica del programa Exclusin mutua Inhabilitacin de interrupciones Alternancia estricta Espera ocupada Sleep y Wakeup
Hilos y Procesos
Alternancia estricta
turno = 1;
region_no_critica(); } }
turno = 0;
region_no_critica();
Hilos y Procesos
El problema del productor y el consumidor
Se tiene un buffer que dos procesos (el productor y el consumidor comparten) El productor genera datos y los coloca en el buffer
Hilos y Procesos
Solucin usando sleep y wakeup
#define N 100 int cuenta = 0; void productor() { while(TRUE) { producir_item(); if (cuenta == N) sleep(); agregar_item(); cuenta = cuenta + 1; if (cuenta == 1) wakeup (consumidor); } } void consumidor() { while(TRUE) { if (cuenta==0)sleep(); sacar_item(); cuenta = cuenta - 1; if (cuenta==N-1) wakeup(productor); consumir_item(); } }
Hilos y Procesos
Se puede presentar el siguiente problema:
El buffer est vaco. El consumidor se dispone a sacar un item Lee la variable cuenta (valor=0). El planificador decide ejecutar al productor El productor agrega un tem, incrementa el contador, y como es igual a 1 llama a wakeup para despertar al consumidor (que debe estar dormido) La llamada se pierde porque el consumidor no est dormido
Hilos y Procesos
Semforos
Un semforo es una variable especial cuyo valor se modifica nicamente mediante dos operaciones: up y down Cuando se invoca la operacin up el valor de la variable se incrementa
Cuando se invoca la operacin down se resta 1 a la variable, a menos que el valor sea 0, en cuyo caso el proceso se bloquea (sleep)
Si al invocar la operacin up hay procesos bloqueados en el semforo se desbloquea el primer proceso. El valor de la variable no se incrementa
Despus de un up con un semforo que tiene procesos esperando, el semforo seguir estando en 0, pero habr un proceso menos esperando
Para que los semforos sean efectivos, las operaciones up y down deben ser atmicas. Esto puede hacerse mediante diversos mecanismos. Ej. deshabilitar interrupciones.
Hilos y Procesos
Solucin usando usando semforos
#define N 100 typedef int semaphore; semaphore mutex=1; semaphore empty=N; semaphore full=0; void productor() { int item; while(TRUE) { producir_item(&item); down(&empty); down(&mutex); agregar_item(item); up(&mutex); up(&full); } } void consumidor() { int item; while(TRUE) { down(&full); down(&mutex); sacar_item(&item); up(&mutex); up(&empty); consumir_item(item); } }
Hilos y Procesos
Monitores
El uso de semforos es propenso a errores Los monitores son primitivas de sincronizacin de ms alto nivel
Monitor: una coleccin de procedimientos, variables y estructuras de datos que se agrupan en un tipo especial de mdulo
Los procesos pueden invocar los procedimientos del monitor pero no acceder a las estructuras de dato internas Solo un proceso o hilo puede invocar un mtodo del monitor a la vez Desventaja. Los monitores tienen que estar implementados a nivel del lenguaje. No pueden implementarse mediante bibliotecas
Hilos y Procesos
Monitor example integer count; condition full, empty; procedure enter; begin if count = N then wait(full); enter_item; count = count + 1; if count = 1 then signal(empty) end; procedure remove; begin if count = 0 then wait(empty); remove_item; count = count - 1; if count = N - 1 then signal(full) end; end monitor;
Hilos y Procesos
procedure producer; begin while true do begin produce_item; ProducerConsumer.enter end end;
procedure consumer; begin while true do begin produce_item; ProducerConsumer.remove end end;
Hilos y Procesos
Hilos en Java
La especificacin no determina el tipo de hilos (hilos del nucleo o hilos de usuario). Ambos son posibles
Utiliza monitores para la sincronizacin cuando hay posibilidades de acceso simultneo a variables
Hilos y Procesos
Crear hilos
Destruir hilos
Declarando una subclase de Thread Declarando una clase que implemente la interfaz Runnable
Hilos y Procesos
public class SimpleThread extends Thread { public SimpleThread(String str) { super(str); } public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + getName()); } }
Hilos y Procesos
public class TwoThreadsDemo { public static void main (String[] args) { Thread t1 = new SimpleThread("Jamaica"); Thread t2 = new SimpleThread("Fiji"); t1.start(); t2.start(); } }
Hilos y Procesos
public class MyClass extends MySuper implements Runnable { public MyClass () { } public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + getName()); } }
Hilos y Procesos
public class TwoThreadsDemo { public static void main (String[] args) { MyClass m1 = new MyClass(); MyClass m2 = new MyClass(); Thread t1 = new Thread(m1, "Hilo 1"); Thread t2 = new Thread(m2, "Hilo 2"); t1.start(); new Thread(m1, "Hilo 3"); } }
Hilos y Procesos
Thread(Runnable target)
Thread(Runnable target, String name) Thread(String name)
Hilos y Procesos
Hilos y Procesos
Ejemplos
Variable de control
boolean continuar=true; void finalizar { continuar = false; } void run() { while (continuar) { ... } }
Hilos y Procesos
Sincronizacin en Java
La palabra syncronized se puede usar para definir mtodos que sean thread safe.
Hilos y Procesos
public class CubbyHole { private int contents; private boolean available = false; public synchronized int get() { while (available == false) { try { wait(); } catch (InterruptedException e) { } } available = false; notifyAll(); return contents; } public synchronized void put(int value) { while (available == true) { try { wait(); } catch (InterruptedException e) { } } contents = value; available = true; notifyAll(); } }
Hilos y Procesos
public class Producer extends Thread { private CubbyHole cubbyhole; private int number; public Producer(CubbyHole c, int number) { cubbyhole = c; this.number = number; } public void run() { for (int i = 0; i < 10; i++) { cubbyhole.put(i); try { sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } } }
Hilos y Procesos
public class Consumer extends Thread { private CubbyHole cubbyhole; private int number; public Consumer(CubbyHole c, int number) { cubbyhole = c; this.number = number; }
public void run() { int value = 0; for (int i = 0; i < 10; i++) { value = cubbyhole.get(); } }
}
Hilos y Procesos
public class ProducerConsumerTest { public static void main(String[] args) { CubbyHole c = new CubbyHole(); Producer p1 = new Producer(c, 1); Consumer c1 = new Consumer(c, 1); p1.start(); c1.start(); } }
Hilos y Procesos
Prioridades
La mquina virtual no especifica el algoritmo de planificacin Cada hilo tiene una prioridad entre Thread.MAX_PRIORITY (10) y Thread.MIN_PRIORITY (1) Inicialmente cada hilo tiene la misma prioridad que el hilo desde donde fue creado. El hilo inicial tiene prioriad 5 getPriority(). Devuelve la prioridad del hilo setPriority(int p). Permite modificar la prioridad del hilo
Hilos y Procesos
Prioridades recomendadas por tipo de tarea
10. Manejo de crisis 7-9. Tareas interactivas, manejadas por eventos 4-6. Tareas intensas en entrada/salida 2-3. Procesamiento en background
Hilos y Procesos
Mtodos de control
thead.interrupt(). Coloca el estatus de interrupcin en true. Si el hilo est dentro de wait(), sleep() o join() se lanza la excepcin InterruptedException
Hilos y Procesos
Mtodos estticos de la clase Thread
Hilos y Procesos
Hilos y Procesos
class Semaphore { private int value; Semaphore (int initial) { value_ = initial; } synchronized public void up() { ++value; notify(); } synchronized public void down() { while (value == 0) { try { wait(); } catch (InterruptedException e){} } --value_; } }
Hilos y Procesos
Mutex
class Mutex { private Semaphore s = new Semaphore(1); public void aquire() { s.down(); } public void release() { s.up(); } }
Hilos y Procesos
Hilos y Procesos
public void release() { if (owner != Thread.currentThread()) { throw new Ownership(); } if (--lockCount <= 0) { owner = null; notify(); } } public void acquire() throws InterruptedException { acquire(FOREVER); } private boolean acquireWithoutBlocking() { Thread current = Thread.currentThread(); if (owner == null) { owner = current; lockCount = 1; } else if (owner == current) { ++lockCount; } return owner == current; } }
Hilos y Procesos
public class SimpleQueue { private static final int QUEUE_SIZE = 10; private Object[] queue = new Object[QUEUE_SIZE]; private int head = 0; private int tail = 0; public synchronized void insert(Object item) { tail = ++tail % QUEUE_SIZE; queue[tail] = item; this.notify(); } public synchronized Object remove(Object item) { try { while (head == tail) { this.wait(); } } catch (InterruptedException e) { return null; } head = ++head % QUEUE_SIZE; Object removedObject = queue[head]; queue[head] = null; return removedObject; } }
Hilos y Procesos
Cuando un hilo A entra a un mtodo synchronized adquiere un semforo mutex para excluir a otros hilos
this.mutex.acquire();
La llamada a wait() libera el semforo mutex para permitir que otros hilos puedan entrar al mtodo this.mutex.release(); this.condition.wait_for_true(); this.mutex.acquire();
Hilos y Procesos
Problema 1. notifyAll().
Si varios hilos llama a remove y la cola est vaca todos se bloquearan en condition.wait_for_true(). Si el mtodo insert usa notify all, todos los hilos se desbloquern simultneamente todos tratarn de adquirir el mutex, pero solo uno ganar El ganador saca un elemento de la cola (la cual queda vaci) y sale de remove, liberando el mutex Los otros hilos se desbloquearn uno tras otro y todos sacarn elementos de una cola vaca
Hilos y Procesos
Problema no. 2. notify()
Si se usa notify() solo un hilo saldr del bloqueo en condition.wait_for_true. El problema 1 no se presenta. Pero se puede presentar este: Un hilo A llama a remove() se bloquea en wait()
Un hilo B llama a insert y por lo tanto a notify, liberando el mutex. El hilo A avanza hasta aqu
this.mutex.release();
A es expropiado. El mtodo insert no ha terminado por lo que B tiene el mutex Un hilo C llama a remove() y se bloquea al tratar de adquirir el mutex A se ejecuta (porque B y C) estn bloqueados y libera el mutex
Hilos y Procesos
Problema no. 2. notify() (cont.)
No hay forma de determinar quin obtiene el mutex (A o C) Si el hilo C obtiene el mutex sacar de la cola el objeto que B insert (no se llama a wait() porque la cola no est vaca
Ahora el hilo A se despierta. Si existe el wait() est dentro de ciclo while se bloquer en wait porque la cola est vaca (porque C sac el objeto que A insert)
Si ho hay un ciclo while sino una instruccin if, A continuar y sacar un objeto de una cola vaca El problema se presenta porque la operacin wait() no tiene que ser atmica.