2.2.2 Implementación
Cada Sistema operativo implementa los hilos del sistema utilizando tres estándares en donde las librerías nativas son:
- Win32.
- OS/2.
- POSIX.
Las dos primeras son propietarias y sólo corren bajo sus respectivas plataformas (NT, Win95, OS/2).
La especificación POSIX (IEEE 1003.1c) conocida como pthreads [Butenhof, 1997] está pensada para todas las plataformas y está disponible para la mayoría de las implementaciones UNIX y Linux, así como VMS y AS/400.
Algunas de las versiones del estándar POSIX pertenecen al primer tipo, mientras que tanto OS/2 como Win32 pertenecen al segundo tipo. Ambos enfoques pueden ser empleados para desplegar exactamente el mismo API.
Se pueden identificar dos modalidades de implementación de los hilos en el sistema operativo:
- La creación de una biblioteca a nivel de usuario, donde todas las estructuras y códigos residirán en el espacio de usuario. En consecuencia, la mayoría de las llamadas realizadas desde la biblioteca se ejecutarán en dicho espacio y no requerirán más recursos del sistema que cualquier otra biblioteca o programa de usuario.
- La implementación a nivel de núcleo, donde la mayoría de las llamadas de la biblioteca exigirán invocaciones al sistema.
Figura 8. Implementación a nivel de usuario.
//Ejemplo 1: //En este modelo, varios hilos de usuario se mapean a un número menor de hilos del sistema operativo, permitiendo una implementación más eficiente y adaptativa de hilos. #include <stdio.h> #include <pthread.h> // Función que será ejecutada por cada hilo void *funcion_hilo(void *arg) { printf("Hilo ejecutado: %d\n", *((int *) arg)); // Imprimir el ID del hilo pthread_exit(NULL); // Terminar el hilo } int main() { pthread_t hilos[4]; // Array para almacenar los identificadores de los hilos int ids[] = {1, 2, 3, 4}; // Array de IDs de los hilos // Crear hilos for (int i = 0; i < 4; i++) { pthread_create(&hilos[i], NULL, funcion_hilo, (void *) &ids[i]); // Crear un nuevo hilo } // Esperar la finalización de los hilos for (int i = 0; i < 4; i++) { pthread_join(hilos[i], NULL); // Esperar a que el hilo con el ID correspondiente termine } return 0; }
Código 3. Modelo de Hilos Independientes (M:N Mapping).
//Ejemplo 2: //En este modelo, los hilos son gestionados y soportados directamente por el sistema operativo a nivel de kernel, proporcionando un mayor nivel de control y //cooperación entre hilos y procesos. #include <stdio.h> #include <pthread.h> // Función que será ejecutada por cada hilo ligero void *funcion_hilo_ligero(void *arg) { printf("Hilo ligero ejecutado: %d\n", *((int *) arg)); // Imprimir el ID del hilo ligero pthread_exit(NULL); // Terminar el hilo ligero } int main() { pthread_t hilos[2]; // Array para almacenar los identificadores de los hilos ligeros int ids[] = {1, 2}; // Array de IDs de los hilos ligeros // Crear hilos ligeros for (int i = 0; i < 2; i++) { pthread_create(&hilos[i], NULL, funcion_hilo_ligero, (void *) &ids[i]); // Crear un nuevo hilo ligero } // Esperar la finalización de los hilos ligeros for (int i = 0; i < 2; i++) { pthread_join(hilos[i], NULL); // Esperar a que el hilo ligero con el ID correspondiente termine } return 0; }
Código 4. Modelo de Hilos Pesados (Heavyweight Threads).
//Ejemplo 3: //En este modelo, los hilos son gestionados completamente a nivel de usuario sin soporte directo del sistema operativo, proporcionando una implementación más ligera y eficiente de hilos. #include <stdio.h> #include <pthread.h> // Función que será ejecutada por cada hilo pesado void *funcion_hilo_pesado(void *arg) { printf("Hilo pesado ejecutado: %d\n", *((int *) arg)); // Imprimir el ID del hilo pesado pthread_exit(NULL); // Terminar el hilo pesado } int main() { pthread_t hilos[3]; // Array para almacenar los identificadores de los hilos pesados int ids[] = {1, 2, 3}; // Array de IDs de los hilos pesados // Crear hilos pesados for (int i = 0; i < 3; i++) { pthread_create(&hilos[i], NULL, funcion_hilo_pesado, (void *) &ids[i]); // Crear un nuevo hilo pesado } // Esperar la finalización de los hilos for (int i = 0; i < 3; i++) { pthread_join(hilos[i], NULL); // Esperar a que el hilo pesado con el ID correspondiente termine } return 0; }
Código 5. Modelo de Hilos Ligeros (Lightweight Threads).
Reflexiona la siguiente pregunta que será tratada en la sesión de clase.
¿Qué diferencias hay entre los hilos pesados y los hilos ligeros?