Pthreads (POSIX Threads)

Pthreads (POSIX Threads) es una API estándar para la creación y gestión de hilos en sistemas operativos compatibles con POSIX, como Linux y FreeBSD. Los hilos permiten que un programa ejecute múltiples tareas en paralelo dentro de un mismo proceso, compartiendo memoria y recursos, pero ejecutándose de manera independiente.

El uso de Pthreads es común en aplicaciones donde se necesita concurrencia (manejar múltiples tareas al mismo tiempo), como en servidores, procesamiento de datos o aplicaciones interactivas. Para manejar los hilos, se utilizan funciones como pthread_create() para crearlos, pthread_join() para esperar su finalización y mecanismos de sincronización como mutexes y semáforos para evitar problemas como condiciones de carrera.

A diferencia de un modelo basado en eventos, donde un solo hilo maneja múltiples tareas reaccionando a eventos sin bloquearse, el uso de múltiples hilos permite ejecutar tareas en paralelo de manera más eficiente en procesadores multinúcleo. Sin embargo, el uso de Pthreads introduce complejidad adicional, ya que los hilos deben coordinarse adecuadamente para evitar errores y optimizar el rendimiento.


IPC (Inter-Process Communication)


*Definir proceso. 


La creación de un hilo puede ser hasta entre 10 a 100 veces más rápida que la creación de un proceso. 

Todos los hilos dentro de un proceso comparten la misma memoria global, directorio actual de trabajo, usuario y grupos, entre otros.

#include <pthread.h>


int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func)(void *), void *arg); 


Retorna 0 como Ok, y un valor positivo Exxx en caso de error.

Pero cada hilo tiene su propio ID, conjunto de registros, puntero a stack, errno, prioridad.  


Cuando un programa comienza a ejecutarse , se crea un hilo, llamado “initial thread” o “main thread”. Los hilos adicionales se crean con “phthread_create”. 

Cada hilo dentro de un proceso se identifica con un “thread ID”, cuyo tipo de dato es pthread_t (generalmente un unsigned int). Cuando un hilo se crea exitosamente devuelve un entero mediante el puntero tid. 

Cada hilo tiene numerosos atributos que pueden ser sobrescritos, pero por lo general se usan los por defecto, en cuyo caso se especifica el argumento attr como un puntero nulo. 

Finalmente se hace una función que lo ejecuta. El hilo termina llamando a pthread_exit o implícitamente dejando a la función retornar un valor. 

Existen dos tipos de hilos: 

1. “Joinable” (Unibles).

Son hilos que no se eliminan automáticamente cuando terminan.

Se debe llamar a pthread_join() para esperar a que terminen y liberar sus recursos.

Son útiles cuando el hilo devuelve información que el programa principal necesita.

Ejemplo:

pthread_t tid;

pthread_create(&tid, NULL, funcion_hilo, NULL);

pthread_join(tid, NULL);  // Espera a que el hilo termine

*) Si no se llama a pthread_join(), el hilo queda como "zombie", consumiendo recursos.


2. “Detached” (Desvinculados).

Son hilos que se eliminan automáticamente cuando terminan.

No necesitan pthread_join().

Útiles para tareas independientes donde no importa cuándo terminan.

Ejemplo: 

pthread_t tid;

pthread_create(&tid, NULL, funcion_hilo, NULL);

pthread_detach(tid);  // El hilo se limpia solo cuando termina

*) Aquí el hilo trabaja solo y no se puede "esperar" con pthread_join().


¿Cuándo usar cada uno?

Tipo de Hilo

Cuándo Usarlo

Joinable

Cuando necesitas recuperar datos del hilo o asegurarte de que termine antes de seguir.

Detached

Cuando el hilo ejecuta una tarea independiente y no necesitas saber cuándo finaliza.

Si necesitas recuperar información o controlar cuándo un hilo termina, usa "joinable". Si solo quieres que haga su trabajo y desaparezca, usa "detached".