Sunteți pe pagina 1din 11

PRCTICA N 09: "PROCESOS LIGEROS Y TUBERIAS"

1. OBJETIVO:

Analizar funcionamiento de procesos ligeros y tuberas en Linux.

2. FUNDAMENTO TERICO:
Hilos (Threads)
Segn (Perez Campanero, 2002) para aprovechar al mximo las capacidades de los
ordenadores multiprocesador, algunos sistemas operativos, y tambin algunos lenguajes de
programacin, permiten a un programa dividirse en varias ramas que se pueden ejecutar en
paralelo. Estas ramas se conocen como hilos o threads.
Cada uno de los hilos se puede ejecutar en un procesador distinto, por lo que se acelera la
ejecucin del programa.
Estos hilos se pueden ejecutar en un procesador distinto, por lo que se acelera la ejecucin del
programa.
Estos hilos podemos considerarlos como procesos dbiles o procesos ligeros. En realidad
forman parte del mismo proceso que ejecuta el programa, pero a su vez, cada hilo tiene asociada
una estructura de datos similar al Bloque de Control de Proceso, que queda dentro de dicho
PCB.
Los hilos heredan el entorno del proceso, y pueden trabajar con l. Igualmente, al crearse el hilo,
se crea la estructura de datos correspondiente, y cuando desaparece el hilo, desaparece dicha
estructura. Al crearse el Bloque de Control del Hilo (TCB), se asigna memoria para la parte de
cdigo del programa que se identifica con dicho hilo.
Segn (Martinez Moreno, 2015) un proceso ligero, o thread, es un programa en ejecucin (flujo
de ejecucin) que comparte la imagen de memoria y otras informaciones con otros procesos
ligeros. Como muestra la Figura, un proceso puede contener un solo flujo de ejecucin, como
ocurre en los procesos clsicos, o ms de un flujo de ejecucin (procesos ligeros).
Desde el punto de vista de la programacin, un proceso ligero se define como una funcin cuya
ejecucin se puede lanzar en paralelo con otras. El hilo de ejecucin primario, o proceso ligero
primario, corresponde a la funcin main.
Cada proceso ligero tiene informaciones que le son propias y que no comparte con otros procesos
ligeros. Las informaciones propias se refieren fundamentalmente al contexto de ejecucin,
pudindose destacar las siguientes:

Contador de programa.
Pila.
Registros.
Estado del proceso ligero (ejecutando, listo o bloqueado).

Todos los procesos ligeros de un mismo proceso comparten la informacin del mismo. En
concreto, comparten:

Espacio de memoria.
Variables globales.
Archivos abiertos.
Procesos hijos.
Temporizadores.
Seales y semforos.
Contabilidad.

Es importante destacar que todos los procesos ligeros de un mismo proceso comparten el mismo
espacio de direcciones de memoria, que incluye el cdigo, los datos y las pilas de los diferentes
procesos ligeros. Esto hace que no exista proteccin de memoria entre los procesos ligeros de
un mismo proceso, algo que si ocurre con los procesos convencionales.
El proceso ligero constituye la unidad ejecutable en Windows NT. La Figura representa de forma
esquemtica la estructura de un proceso de Windows NT con sus procesos ligeros.

Ilustracin 1: Procesos ligeros

Redireccin, tuberas y filtros:


Segn (Quero Catalinas, 2003) la redireccin y las tuberas o pipes son una de las caractersticas
que dan potencia y flexibilidad a UNIX. Su principal objetivo es la interconexin de procesos, de
manera que la salida estndar de una orden pueda ser redirigida a cualquier otro dispositivo o
fichero.
Existen cuatro operadores para redireccionar la salida o entrada estndar de una orden o
comando, <, >, <<, >>.
Las tuberas o pipes, permiten tomar la salida de un comando como entrada de otro. Estos
comandos se enlazan entre s a travs del operador | (barra vertical). El formato de utilizacin
de una tubera seria el siguiente, donde la salida del comando1 enlaza con la entrada del
comando2.
$comando1 | comando2
Los filtros son programas que manipulan la salida de un comando antes de que esta sea
mostrada o volcada sobre el dispositivo correspondiente o utilizado por un segundo comando.
Los filtros se pueden combinar con las tuberas y la redireccin.
Segn (Arjuno3, 2015) en informtica, una tubera (pipe, cauce o '|') consiste en una cadena
de procesos conectados de forma tal que la salida de cada elemento de la cadena es la entrada
del prximo. Permiten la comunicacin y sincronizacin entre procesos. Es comn el uso
de buffer de datos entre elementos consecutivos.
La comunicacin por medio de tuberas se basa en la interaccin productor/consumidor, los
procesos productores (aquellos que envan datos) se comunican con los procesos consumidores
(que reciben datos) siguiendo un orden FIFO. Una vez que el proceso consumidor recibe un
dato, ste se elimina de la tubera.
Las tuberas (pipes) estn implementadas en forma muy eficiente en los sistemas
operativos multitarea, iniciando todos los procesos al mismo tiempo, y atendiendo
automticamente los requerimientos de lectura de datos para cada proceso cuando los datos

P g i n a 2 | 11

son escritos por el proceso anterior. De esta manera el planificador de corto plazo va a dar el
uso de la CPU a cada proceso a medida que pueda ejecutarse minimizando los tiempos muertos.
Para mejorar el rendimiento, la mayora de los sistemas operativos implementan las tuberas
usando buffers, lo que permite al proceso proveedor generar ms datos que lo que el proceso
consumidor puede atender inmediatamente.
Podemos distinguir dos tipos de tuberas:
Tubera sin nombre
Las tuberas sin nombre tienen asociado un fichero en memoria principal, por lo tanto, son
temporales y se eliminan cuando no estn siendo usados ni por productores ni por consumidores.
Permiten la comunicacin entre el proceso que crea un cauce y procesos hijos tras la creacin
de la tubera.
Tubera con nombre
Su diferencia respecto a las tuberas sin nombre radica en que el cauce se crea en el sistema de
archivos, y por lo tanto no tienen carcter temporal. Se manejan mediante llamadas al
sistema (open, close, read y write) como el resto de ficheros del sistema. Permiten la
comunicacin entre los procesos que usen dicha tubera, aunque no exista una conexin
jerrquica entre ellos.
3. PROCEDIMIENTO

Abrir la terminal de Linux y como en el anterior informe crear un fichero en ejecutar el cdigo en
C++

Ejemplo01.c
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
void *hilo1(void *arg)
{
int i;
for(i=0;i<10;i++)
{
printf("Mensaje Generado Hilo1\n");
}
return(NULL);
}
int main(void)
{
pthread_t mihilo;
int i;
printf("Esperando finalizacion de hilos\n");
if(pthread_create(&mihilo,NULL,hilo1,NULL))
{
printf("Mensaje Generado por Main\n");
abort();
}

P g i n a 3 | 11

for(i=0;i<10;i++)
{
printf("Mensaje Generado por Main\n");
}
if(pthread_join(mihilo,NULL))
{
printf("Error esperando finalizacion de hilos");
abort();
}
printf("Fin de ejecucin de hilos\n");
exit(0);

Se ejecuta el cdigo en la terminal dndonos la siguiente salida.

Interpretacin:
En la funcin main se ha declarado la variable mihilo, que es del tipo pthread_t (definido en la
librera pthread.h). El tipo pthread_t es llamado id del hilo y es usado como una especie de
identificador o manejador (thread). Seguidamente llamamos a la funcin pthread_create que como
su nombre indica creara un hilo. La funcin pthread_create dentro de un if() debido a que esta
funcin devuelve un cero si el hilo fue creado exitosamente y un valor diferente de cero si fallo.
Asi detectamos si fallo o no. El primer argumento de la funcin es un puntero a la variable
&mihilo. El segundo es NULL. El tercer argumento se ejecutara cuando la funcin nuevo hilo
empieze, retornara algn valor cuando este termine. Este programa consiste en dos hilo ya que la
funcin main tambin se considera como un hilo. Al ejecutar la lnea pthread_join une los hilos
(threads) en uno solo.
Ejemplo02.c
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>

P g i n a 4 | 11

#include<unistd.h>
void *hilo1(void *arg)
{
int i;
for(i=0;i<10;i++)
{
printf("Mensaje Hilo #1\n");
}
return(NULL);
}
void *hilo2(void *arg)
{
int i;
for(i=0;i<10;i++)
{
printf("Mensaje Hilo #2\n");
sleep(1);
}
return(NULL);
}
void *hilo3(void *arg)
{
int i;
for(i=0;i<10;i++)
{
printf("Mensaje Hilo #3\n");
sleep(1);
}
return(NULL);
}
int main(void)
{
pthread_t mihilo_1;
pthread_t mihilo_2;
pthread_t mihilo_3;
if(pthread_create(&mihilo_1,NULL,hilo1,NULL))
{
printf("Error creando hilo1");
abort();
}
if(pthread_create(&mihilo_2,NULL,hilo2,NULL))
{
printf("Error creando hilo2");
abort();
}
if(pthread_create(&mihilo_3,NULL,hilo3,NULL))
{
printf("Error creando hilo3");
abort();
}
printf("Esperando finalizacion de hilos\n");
int i;
for(i=0;i<10;i++)
{

P g i n a 5 | 11

printf("Mensaje Generado por Main\n");


}
if(pthread_join(mihilo_1,NULL))
{
printf("Error esperando finalizacion de hilo 1");
abort();
}
if(pthread_join(mihilo_2,NULL))
{
printf("Error esperando finalizacion de hilo 2");
abort();
}
if(pthread_join(mihilo_3,NULL))
{
printf("Error esperando finalizacion de hilo 3");
abort();
}
printf("Fin de ejecucin de hilos\n");
exit(0);
}
Se ejecuta el cdigo del ejemplo02.c dndonos la siguiente salida.

P g i n a 6 | 11

Interpretacin:
En la funcin main se ha declarado la variable mihilo_1, mihilo_2 y mihilo_3; son del tipo pthread_t
(definido en la librera pthread.h). El tipo pthread_t es llamado id del hilo y es usado como una
especie de identificador o manejador (thread). Seguidamente llamamos a la funcin
pthread_create que como su nombre indica creara un hilo. La funcin pthread_create dentro de
un if() debido a que esta funcin devuelve un cero si el hilo fue creado exitosamente y un valor
diferente de cero si fallo. Asi detectamos si fallo o no.
El primer argumento de la funcin es un puntero a la variable &mihilo_1. El segundo es NULL. El
tercer argumento se ejecutara cuando la funcin nuevo hilo empieze, retornara algn valor cuando
este termine seguir el mismo paso con el hilo_2 y el hilo_3. Este programa consiste en cuatro
hilos ya que la funcin main tambin se considera como un hilo. Al ejecutar la lnea pthread_join
une los hilos (threads) en uno solo.
Tuberia01.c
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define LEER 0
#define ESCRIBIR 1
int main()
{
int descr[2]; /*Descriptores de E y S de la tuberia */
int bytesleidos;
char mensaje[100], *frase="Hola mundo";
printf("**Ejemplo de comunicacion de padre e hijo**\n\n");
pipe(descr);
if(fork()==0)
{
/*Seccion hijo*/

P g i n a 7 | 11

close(descr[LEER]);
write(descr[ESCRIBIR],frase,strlen(frase));
close(descr[ESCRIBIR]);
}
else
{
/*Seccion padre*/
close(descr[ESCRIBIR]);
bytesleidos=read(descr[LEER],mensaje,100);
mensaje[bytesleidos]='\0';
printf("Bytes leidos: %d\n",bytesleidos);
printf("Mensaje enviado por el hijo: %s\n",mensaje);
close(descr[LEER]);
}
}

Editamos un fichero lo ejecutamos

Interpretacin:
En las tuberas sin nombre o PIPES sin nombre solo se puede mandar mensaje entre procesos
emparentados. El siguiente programa muestra un proceso padre se puede comunicar con su hijo
haciendo uso de tuberas sin nombre, el proceso padre le proporciona una cadena al proceso hijo
y este lo imprimir en pantalla.
productor.c
/*productor*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<string.h>

P g i n a 8 | 11

int main(int argc, char *argv[]){


int bandera, fd; /*file descriptor*/
char *nfifo="fifo";
printf("productor\n\n");
if(argc !=2){
fprintf(stderr, "modo de uso: ./productor mensaje\n");
exit(1);
}
/*creando la tuberia*/
bandera=mkfifo(nfifo, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
if(!bandera){
/*abriendo la tuberia en modo escritura (productor)*/
printf("productor espera apertura del consumidor\n");
fd=open(nfifo, O_WRONLY);
if(fd==-1)
perror("error al abrir la tuberia (escritura)\n");
else{
/*escritura en la tuberia*/
write(fd, argv[1], 100);
printf("productor envio: %s\n",argv[1]);
close(fd);
}
}
else
perror("error al crear la tuberia\n");
return 0;
}

consumidor.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
char mensaje[100], *nfifo="fifo";
int fd; /*file descriptor*/
printf("consumidor\n\n");
/*leendo en la tuberia (consumidor)*/
fd=open(nfifo, O_RDONLY);
if(fd==-1)
perror("error al abrir la tuberia (lectura)\n");
else{
/*lectura de la tuberia*/
read(fd, mensaje, 100);
printf("consumidor recibio: %s\n", mensaje);
close(fd);
}

P g i n a 9 | 11

/*eliminando tuberia*/
unlink(nfifo);
}
La siguiente captura de pantalla muestra la salida de la ejecucin del productor y consumidor.

Interpretacin:
El productor mandara un mensaje de texto el cual ser almacenado en la tubera, luego el
consumidor recobrara ese mensaje para desplegarlo en la pantalla.
4. ANEXOS:

01 nano ejemplo01.c
02 gcc ejemplo01.c -o ejemplo01 -pthread
03 ./ejemplo01
04 nano ejemplo02.c
05 gcc ejemplo02.c -o ejemplo02 -pthread
06 ./ejemplo02
07 gcc ejemplo02.c -o ejemplo02 -pthread
08 ./ejemplo02
09 nano tuberia01.c
10 gcc tuberia01.c -o tuberia01 -pthread
11 ./tuberia01
12 nano productor.c
13 gcc productor.c -o productor -pthread
14 nano productor.c

P g i n a 10 | 11

15 gcc productor.c -o productor -pthread


16 nano productor.c
17 gcc productor.c -o productor -pthread
18 ./productor
19 nano consumidor.c
20 gcc consumidor.c -o consumidor -pthread
21 ./consumidor
22 history >> mandatos_practica_09

5. CONCLUSIONES:

Observamos cmo se ejecuta un cdigo en C++ desde la terminal Shell, as un proceso


ligero son hilos que desaparecen cuando finaliza su ejecucin, en los primeros ejemplos
se visualiza la creacin de los hilos pthread_create, pthread_join los unir en uno solo; los
mensajes se imprimirn en pantalla, en la tubera se observa la comunicacin entre el
proceso padre e hijo donde deben estar emparentados, el proceso padre le enva una
cadena al proceso hijo.

6. BIBLIOGRAFIA:

Arjuno3. (20 de Marzo de 2015). Tubera (informtica). Obtenido de Wikipedia Web


site: https://es.wikipedia.org/wiki/Tuber%C3%ADa_(inform%C3%A1tica)
Martinez Moreno, M. (12 de Junio de 2015). Procesos Ligeros (Hilos o Hebras).
Obtenido
de
Angelfire
Web
site:
http://sistemasoperativos.angelfire.com/html/2.3.html
Perez Campanero, J. A. (2002). Conceptos de sistemas operativos. Madrid:
Universidad Pontificia Comillas.
Quero Catalinas, E. (2003). Sistemas operativos y lenguajes de programacin.
Madrid: Thomson Paraninfo.

P g i n a 11 | 11

S-ar putea să vă placă și