Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

ACTIVIDAD 6

ANDRES MAURICIO TIBAQUIRA RODRIGUEZ

FUNDACION UNIVERSITARIA UNIPANAMERICANA

SISTEMAS OPERATIVOS

2020
INTRODUCCION

El siguiente trabajo hace referencia a la gestión de procesos y threads.


OBJETIVOS

- Analizar comportamiento sobre gestión de procesos y threads.


- Identificar los diferentes comportamientos en threads.
- Examinar la trazabilidad durante la gestión de procesos.
ACTIVIDAD

Práctica 1

Gestión de procesos y threads

Desarrollar un programa que cree varios procesos concurrentes, que escriban periódicamente
mensajes diferentes en la pantalla Hacer lo mismo con threads periódicos. Pasar a cada thread
como parámetros el periodo y el mensaje a escribir. Los threads se crearán en estado
"independiente" Para ello se utiliza el siguiente código.

//para lanzar hilos se hacen desde objetos

//que heredan de thread

//con star se lanzan los hilos

package javaapplication76;

import java.util.Timer;

import java.util.TimerTask;

import java.util.logging.Level;

import java.util.logging.Logger;

public class principal extends Thread{

private int id;

public principal (int id){

this.id = id;

public void run() {

System.out.println("Mensaje generado por el hilo Numero: "+id);

}
public static void main(String[] args) throws InterruptedException {

principal h1 = new principal(1);

principal h2 = new principal(2);

principal h3 = new principal(3);

Thread.sleep(2000);

h1.start();

Thread.sleep(2000);

h2.start();

Thread.sleep(2000);

h3.start();

Thread.sleep(2000);

System.out.println("Mensaje generado por el hilo principal");

}
El periodo es de 3 segundos por hilo.

Práctica 2 Ficheros

Escribir un programa que copie los contenidos de un fichero en otro. Se pasarán los nombres
como argumentos al programa. Modificarlo para que ponga el estado del fichero generado
según los parámetros de entrada que se le pasen los permisos del usuario (rwx) Asimismo,
deberá presentar información del estado de los ficheros (original y copia) en pantalla (fechas,
tamaño, etc.) En el desarrollo de este ejercicio se utilizó el siguiente script,

import java.io.*;

public class CopiarFicherosYCarpetas {

public static int EntraIncial=0;

public static void main(String[] args) {

//ruta de la carpeta que vamos a copiar

File FOrigen=new File("T:\\portatil\\universidad\\quinto semestre");

//ruta de donde vamos a copiar la carpeta

File FDestino=new File("C:\\Users\\andres\\Desktop\\");

Copiar(FOrigen,FDestino);

EntraIncial=0;

public static void Copiar(File FOrigen,File FDestino){

//verificamos si el origen es una carpeta

if(!FOrigen.isDirectory()){
CopiarFichero(FOrigen,FDestino);

}else{

EntraIncial++;

if(EntraIncial==1){

FDestino=new File(FDestino.getAbsolutePath()+"/"+FOrigen.getName());

if(!FDestino.exists()){

FDestino.mkdir();

String []Rutas=FOrigen.list();

for(int i=0;i<Rutas.length;i++){

File FnueOri=new File(FOrigen.getAbsolutePath()+"/"+Rutas[i]);

File FnueDest= new File(FDestino.getAbsolutePath()+"/"+Rutas[i]);

if(FnueOri.isDirectory() && !FnueDest.exists()){

FnueDest.mkdir();

Copiar(FnueOri,FnueDest);

public static void CopiarFichero(File FOrigen,File FDestino){

try {

if(FOrigen.exists()){

String copiar="S";

if(FDestino.exists()){

System.out.println("El fichero ya existe, Desea Sobre Escribir:S/N ");

copiar = ( new BufferedReader(new InputStreamReader(System.in))).readLine();

if(copiar.toUpperCase().equals("S")){

FileInputStream LeeOrigen= new FileInputStream(FOrigen);


OutputStream Salida = new FileOutputStream(FDestino);

byte[] buffer = new byte[1024];

int tamaño;

while ((tamaño = LeeOrigen.read(buffer)) > 0) {

Salida.write(buffer, 0, tamaño);

System.out.println(FOrigen.getName()+" Copiado con Exito!!");

Salida.close();

LeeOrigen.close();

}else{

System.out.println("El fichero a copiar no existe..."+FOrigen.getAbsolutePath());

} catch (Exception ex) {

System.out.println(ex.getMessage());

Esta es la carpeta de destino, donde se evidencia que no está la carpeta


Aquí vemos la ruta de origen y destino de la carpeta que va a ser copiada y procedemos a
ejecutar el programa.

Aquí vemos que ya fue copiada.

Práctica 3- Threads

Escribir un programa con tres threads que se sincronicen para acceder de manera
mutuamente exclusiva a un conjunto de datos que representan las coordenadas x, y, z de un
cuerpo en el espacio Uno de los threads deberá modificar los datos de manera periódica según
las siguientes ecuaciones (una recta):

x = x + 0, 1 y = 3x + 8 z = 4x – 2y + 3
Otro thread consulta esa información y muestra x, y, z y también (y-3x), que debe ser 8

Otro thread consulta esa información y muestra x, y, z y también (z-4x+2y), que debe ser 3

Para la protección de los datos se usará un mutex.

El programa se ejecutará con y sin protección, y así podrá observarse la inconsistencia del
conjunto de datos cuando no hay protección Puede utilizarse el "come tiempos" que se
encuentra en los ficheros load.c y load.h disponibles en el servidor. Cópialos en tu directorio de
trabajo.

// Creamos estructura para pase de parámetros

struct pthread_st {

double X1;

double X2;

double X3;

};

...

...

int main () {

// definimos una variable de tipo estructura creada

pthread_st pthread_data;

...

// asignamos valores a los parámetros antes de crear la

hebra

pthread_data.X1:=1;

pthread_data.X2:=2;

pthread_data.X3:=3;

// pasamos como parámetro la dirección de la variable de

tipo estructura

// redefinida como puntero void.

pthread_create( &pthread_id, &attr, controller, (void *)

&pthread_data);

...

...

...
}

// recogida de parámetros en la rutina de inicio

void * controller (void *parms) {

double X;

double Y;

double Z;

// definimos una variable tipo puntero a estructura

pthread_st *pthread_dt;

// asignamos el valor del puntero pasado como parámetro

“parms”, el cual

// ‘apunta’ a la variable pthread_data definida en main(),

a la

// variable local pthread_dt.

thread_data=(pthread_st *) parms; // redefinimos el tipo de

“parms”

// asignamos los valores pasados a varibales internas

// en X,Y,Z tendremos los valores 1, 2, 3.

X=thread_data->X1;

Y=thread_data->X2;

Z=thread_data->X3;

...

...

...

Práctica 4 – threads II

Escribir un programa con un thread productor de datos y un thread consumidor de estos


datos. Los datos serán strings. Tanto el productor como el consumidor tendrán tiempos de
ejecución aleatorios dentro de un rango (usar load.h) Utilizarán una variable compartida para
la comunicación contiene un string y un booleano que dice si hay un dato válido o no Utilizarán
un mutex para acceder a la variable Utilizarán dos variables condicionales. Una para que el
productor espere cuando la variable compartida está ocupada Otra para que el consumidor
espere cuando la variable compartida está vacía. Una vez realizado el programa, jugar con él
variando los rangos de los tiempos; practicar con un productor muy rápido o muy lento,
consumidores iguales, o uno más lento, o más rápido, etc.

Para la solución de este ejercicio se utilizó el siguiente código.

//CODIGO EXTRAIDO DE http://dis.um.es/~bmoros/Tutorial/parte10/cap10-6.html

class Productor extends Thread {

private Tuberia tuberia;

private String alfabeto = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

public Productor( Tuberia t ) {

// Mantiene una copia propia del objeto compartido

tuberia = t;

public void run() {

char c;

// Mete 10 letras en la tubería

for( int i=0; i < 10; i++ )

c = alfabeto.charAt( (int)(Math.random()*26 ) );

tuberia.lanzar( c );

// Imprime un registro con lo añadido

System.out.println( "LETRA ASIGNADA "+c+" " );

// Espera un poco antes de añadir más letras

try {

sleep( (int)(Math.random() * 100 ) );

} catch( InterruptedException e ) {

}
}

class Consumidor extends Thread {

private Tuberia tuberia;

public Consumidor( Tuberia t ) {

// Mantiene una copia propia del objeto compartido

tuberia = t;

public void run() {

char c;

// Consume 10 letras de la tubería

for( int i=0; i < 10; i++ )

c = tuberia.recoger();

// Imprime las letras retiradas

System.out.println( "LETRA ELIMINADA "+c );

// Espera un poco antes de coger más letras

try {

sleep( (int)(Math.random() * 2000 ) );

} catch( InterruptedException e ) {

}
class Tuberia {

private char buffer[] = new char[6];

private int siguiente = 0;

// Flags para saber el estado del buffer

private boolean estaLlena = false;

private boolean estaVacia = true;

// Método para retirar letras del buffer

public synchronized char recoger() {

// No se puede consumir si el buffer está vacío

while( estaVacia == true )

try {

wait(); // Se sale cuando esta Vacía cambia a false

} catch( InterruptedException e ) {

// Decrementa la cuenta, ya que va a consumir una letra

siguiente--;

// Comprueba si se retiró la última letra

if( siguiente == 0 )

estaVacia = true;

// El buffer no puede estar lleno, porque acabamos de consumir

estaLlena = false;

notify();

// Devuelve la letra al thread consumidor

return( buffer[siguiente] );

}
// Método para añadir letras al buffer

public synchronized void lanzar( char c ) {

// Espera hasta que haya sitio para otra letra

while( estaLlena == true )

try {

wait(); // Se sale cuando estaLlena cambia a false

} catch( InterruptedException e ) {

// Añade una letra en el primer lugar disponible

buffer[siguiente] = c;

// Cambia al siguiente lugar disponible

siguiente++;

// Comprueba si el buffer está lleno

if( siguiente == 6 )

estaLlena = true;

estaVacia = false;

notify();

class ejercicio4 {

public static void main( String args[] ) {

Tuberia t = new Tuberia();

Productor p = new Productor( t );

Consumidor c = new Consumidor( t );

p.start();

c.start();
}

Práctica 5 - Señales

Probar el programa enviándole señales desde una shell (con la orden kill -num_señal pid)

Nota: Según la versión de Linux se pueden crear (incorrectamente) varios procesos si hay
manejadores de señal.

#include <dirent.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

// Aquí se declaran las variables globales

// y los prototipos de las funciones

int main();

int main() {

int cuenta=0;

DIR * dir;
char directorio[255];

struct dirent* entrada;

if (getcwd(directorio, 255)== NULL) {

perror("Error obteniendo dir. actual: ");

return -1;

dir = opendir(directorio);

if (dir == NULL) {

perror("Error abriendo directorio: ");

return -1;

entrada = readdir(dir);

while(entrada != NULL) {

cuenta++;

//free(entrada);

entrada = readdir(dir);

printf("Entradas: %i\n", cuenta);

if (closedir(dir) == -1) {

perror("Error cerrando directorio: ");

return -1;

return 0;

Práctica 6 - Planificación

Escribir un programa que cree dos threads periódicos concurrentes. A cada thread se le pasará
como parámetro:

periodo

tiempo de ejecución

número de identificación
Para hacer threads periódicos se usará la función clock_nanosleep()

Inicialmente se pueden hacer pseudo-periódicos con sleep ()

Para simular el tiempo de ejecución se usa la función eat () suministrada

Cada décima de segundo de tiempo de ejecución consumido se pondrá un mensaje en la


pantalla con el identificador del thread

También se pondrán mensajes al inicio y final del periodo A partir de la secuencia de ejecución
dibujar un diagrama temporal de la ejecución Tratar de inferir a partir del diagrama el tipo de
planificación (expulsora o no; cíclica, FIFO,...); probar con dos combinaciones diferentes de
periodos y tiempos de ejecución Compilar y ejecutar el programa desarrollado para Linux en el
sistema operativo Marte OS sobre máquina desnuda:

Hacer las mismas pruebas que en el caso anterior Para ello:

Ajustar la variable PATH ejecutando

. /usr/local/marte-1.9/martevars.sh

compilar el programa con mgcc

Copiar el programa en el servidor

cp el_programa /net/lctrserver/mprogram_HOSTNAME

Encender el computador (PC industrial)

class TareaCompleja implements Runnable{

@Override

public void run() {

for (int i=0; i<100;i++){

int a=i*3;

Thread hiloActual=Thread.currentThread();

String miNombre=hiloActual.getName();

System.out.println(

"Finalizado el hilo"+miNombre);

public class LanzadorHilos {

public static void main(String[] args) {

int NUM_HILOS=100;

Thread[] hilosAsociados;
hilosAsociados=new Thread[NUM_HILOS];

for (int i=0;i<NUM_HILOS;i++){

TareaCompleja t=new TareaCompleja();

Thread hilo=new Thread(t);

hilo.setName("Hilo: "+i);

hilo.start();

hilosAsociados[i]=hilo;

/* Despues de crear todo, nos aseguramos

* de esperar que todos los hilos acaben. */

for (int i=0; i<NUM_HILOS; i++){

Thread hilo=hilosAsociados[i];

try {

//Espera a que el hilo acabe

hilo.join();

} catch (InterruptedException e) {

System.out.print("Algun hilo acabó ");

System.out.println(" antes de tiempo!");

System.out.println("El principal ha terminado");

BUCLE

Random generador= new Random();

int numAzar=(1+generador.nextInt(5))*100;

for (int i=0; i<numAzar;i++){


int a=i*3;

Práctica 7- Planificación - II

Escribir un programa que cree varios threads periódicos planificados por prioridades fijas, y
que se sincronizan para utilizar un recurso compartido.

Inicialmente se protegerá este recurso compartido por medio de un mutex convencional.

Los threads calcularán sus tiempos de respuesta de peor caso y cada vez que se produzca un
tiempo peor lo pintarán en la pantalla. Eligiendo de manera adecuada los tiempos de ejecución
y el instante de comienzo de cada tarea se podrá observar el fenómeno de la inversión de
prioridad no acotada, por el que una tarea de alta prioridad tiene que esperar a la finalización
de una tarea de baja prioridad.

A continuación se modificará el programa anterior que sufría inversión de prioridad para


evitarla por medio del uso de un mutex:

Usar el protocolo de protección de prioridad.

Observar cómo la inversión de prioridad se minimiza, y el thread de alta prioridad tiene un


tiempo de respuesta mucho menor.

Comprobar el comportamiento en Marte OS

Thread hilo1;

Thread hilo2;

Thread hilo3;

ilo1 = new Thread (this);

hilo2 = new Thread (this);

hilo3 = new Thread (this);

hilo1.start ();

hilo2.start ();

hilo3.start ();

public void corredor1 () {


c1++;

public void corredor2() {

c2++;

public void corredor3() {

c3++;

Thread ct = Thread.currentThread();

while (ct == hilo1) {

corredor1();

System.out.println("Corredor 1: " + c1);

while (ct == hilo2) {

corredor2();

System.out.println("Corredor 2: " + c2);

while (ct == hilo3) {


corredor3();

System.out.println("Corredor 3: " + c3);

Práctica 8 - Shell

Escribir un script para ser ejecutado por una Shell: que permita cambiar de nombre a todos los
ficheros de un directorio añadiéndoles a todos una extensión la extensión y el nombre del
directorio serán parámetros que se pasen al script Probarlo creando un directorio de prueba
con varios ficheros.

Escribir un segundo script que invoque al primero para todos los directorios contenidos en el
directorio de trabajo. Este segundo script tendrá un único argumento: la extensión a añadir al
nombre de cada fichero Probarlo creando un directorio de prueba con varios directorios, que a
su vez tengan varios ficheros.

Primeramente se hizo el archivo para crear archivos.


Como vemos aquí se crearon los archivos de texto, ahora creamos el archivo para modificar la
extensión de los archivos de manera masiva.
Ahora abrimos el archivo.

Como vemos en la imagen anterior se ejecutó el código donde cambia la extensión de los
archivos y luego ejecuta el archivo para crear más archivos de texto, presionamos una tecla
para continuar y cerrar el programa.
Como vemos aquí se realizó el cambio de la extensión de los archivos de txt a jpeg y con el otro
archivo se volvieron a crear los archivos txt.
CONCLUSIONES

- En conclusión al tema tratado, se puede determinar la manera de gestión de


procesos y threads.
- En este sentido pudimos obtener el respectivo aprendizaje sobre las formas en
gestión de procesos.

You might also like