Introducción a la programación de Hilos

 Universidad de las Fuerzas Armadas

Departamento de Ciencias de la Computación 

Nombres y Apellidos: Erick Gabriel Maldonado Miranda

Asignatura: Interfaces Multimedia                                           NRC: 5435

Aplicativo Web de Sistemas Operativos

Módulo de Sistemas Operativos

Tema Unidad 2 : Introducción a la programación de Hilos


Concurrencia 



La noción de que conjuntos independientes de operaciones pueden estar ocurriendo al mismo tiempo dentro de la máquina cuando se ejecuta un  programa. Por ejemplo, cuando un programa realiza E / S (por ejemplo, a un disco), la CPU puede conmutarse de modo que pueda trabajar en alguna otra tarea mientras se realiza la E / S. Los sistemas operativos permiten al usuario administrar la concurrencia y también (en muchos casos) explotar la concurrencia en nombre del usuario para mejorar el rendimiento. Como resultado, la simultaneidad y la gestión / control de la simultaneidad serán temas que se repiten a lo largo de este curso.

Hilos 

Los subprocesos son una abstracción de programación que está diseñada para permitir que un programador controle la concurrencia y la asincronía dentro de un programa. En algunos lenguajes de programación, como Java, los hilos son "ciudadanos de primera clase" en el sentido de que forman parte de la propia definición del lenguaje. Para otros, como C y C ++, los subprocesos se implementan como una biblioteca a la que se puede llamar desde un programa, pero por lo demás no se consideran parte de la especificación del lenguaje.


Algunas de las diferencias entre tener subprocesos "en el idioma" y subprocesos "como una biblioteca" son a menudo sutiles. Por ejemplo, un compilador de C no necesita tener en cuenta el control de subprocesos, mientras que un compilador de Java debe hacerlo. Sin embargo, una diferencia obvia es que en el caso de la biblioteca, es posible utilizar diferentes bibliotecas de subprocesos con el mismo idioma.

Los subprocesos Kthreads y POSIX son similares en el sentido de que ambos son abstracciones de subprocesos y ambos se implementan como bibliotecas a las que se puede llamar desde un programa en C. Son diferentes en que los subprocesos POSIX requieren soporte del sistema operativo para funcionar correctamente y, por lo tanto, no se pueden usar directamente para implementar el sistema operativo.

¿Qué es un hilo?

Hay muchos tipos diferentes de abstracciones de hilos. En esta clase, usaremos la típica abstracción de "subproceso del sistema operativo" que sustenta los subprocesos POSIX, pero en particular para los subprocesos definidos por el lenguaje, son posibles diferentes definiciones.

De manera abstracta, para nuestros propósitos, un hilo es tres cosas:

• Una lista secuencial de instrucciones que se ejecutarán

• Un conjunto de variables locales que "pertenecen" al hilo (hilo privado)

• Un conjunto de variables globales compartidas que todos los subprocesos pueden leer y escribir


Hilos versus procesos

Recuerde de sus experiencias de programación en C, que su programa compilado se convierte en un "proceso" cuando lo ejecuta. Discutiremos los procesos y lo que realmente son en detalle, pero en esta etapa, es suficiente saber que un programa en C se ejecuta como un proceso cuando se ejecuta en, digamos, un sistema Linux.

El programa AC también define una lista secuencial de instrucciones, variables locales y variables globales, por lo que es posible que se pregunte "¿Cuál es la diferencia entre un hilo y un proceso?"

La respuesta es "no mucho" siempre que haya un solo hilo. Sin embargo, como se discutió anteriormente, los subprocesos son una abstracción diseñada para administrar la simultaneidad, lo que significa que es posible tener varios subprocesos "ejecutándose" al mismo tiempo. Dicho de otra manera,

Un programa C estándar cuando se ejecuta es un proceso con un hilo. Sin embargo, es posible (usando una biblioteca de subprocesos) escribir un programa en C que defina múltiples subprocesos. Eso es Un programa C con subprocesos, cuando se ejecuta, es un proceso que contiene uno o más subprocesos.

Además, estos subprocesos son lógicamente independientes y, por lo tanto, pueden ejecutarse simultáneamente. No tienen que serlo (depende de la implementación) pero la abstracción dice que los hilos son independientes.

¿Por qué hilos?

Hay muchas razones para programar con hilos. En el contexto de esta clase, hay dos importantes:

• Le permiten lidiar con eventos asincrónicos de manera sincrónica y eficiente.

• Le permiten obtener un rendimiento paralelo en un multiprocesador de memoria compartida.


Calcular el promedio usando un hilo

El siguiente programa realiza el mismo cálculo, pero lo hace utilizando un solo hilo en lugar de en el cuerpo principal como en el programa anterior. La versión completa de este programa está disponible en http://www.cs.ucsb.edu/~rich/class/cs170/notes/IntroThreads/example/avg-1thread.c


#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <pthread.h>

char * Usage = "uso: avg-1thread count";

#define RAND () (drand48 ()) / * generador básico de números aleatorios de Linux * /

estructuraarg_struct

{

int tamaño;

datos dobles *;

};

estructura result_struct

{

doble suma;

};

vacío * SumThread (vacío * arg)

{

int i;

doble my_sum;

struct arg_struct * my_args;

int my_size;

doble * my_data;

estructura result_struct * resultado;

printf ("suma hilo en ejecución \ n");

fflush (salida estándar);

my_args = (struct arg_struct *) arg;

resultado = (estructura estructura_resultado *) malloc (tamañoof (estructura estructura_resultado));

my_size = my_args-> size;

my_data = my_args-> data;

gratis (my_args);

my_sum = 0.0;

para (i = 0; i <mi_tamaño; i ++) {

mi_suma + = mis_datos [i];

}

resultado-> suma = mi_suma;

printf ("suma hilo terminado, devolviendo \ n");

fflush (salida estándar);

return ((void *) resultado);

}

int main (int argc, char ** argv)

{

int i;

int n;

datos dobles *;

int count;

struct arg_struct * args;

pthread_t thread_id;

estructura result_struct * resultado;

int err;

count = atoi (argv [1]); / * el recuento es el primer argumento * /

datos = (doble *) malloc (recuento * tamaño de (doble));

para (i = 0; i <cuenta; i ++) {

datos [i] = ALEATORIO ();

}

args = (estructura arg_struct *) malloc (tamaño de (estructura arg_struct));

args-> tamaño = recuento;

argumentos-> datos = datos;

printf ("hilo principal bifurcando la suma del hilo \ n");

fflush (salida estándar);

err = pthread_create (& thread_id, NULL, SumThread, (void *) args);

printf ("subproceso principal que se ejecuta después de la suma del subproceso creado, a punto de llamar a join \ n");

fflush (salida estándar);

err = pthread_join (thread_id, (void **) & result);

printf ("hilo principal unido con hilo de suma \ n");

fflush (salida estándar);

printf ("el promedio sobre% d números aleatorios en (0,1) es% f \ n",

cuenta, resultado-> suma / (doble) cuenta);

gratis (resultado);

gratis (datos);

return (0);

}

Comentarios