Cuando queremos hacer un programa que empieze a ejecutar varias cosas al mismo tiempo tenemos 2 opciones, Crear un nuevo proceso o crear un nuevo hilo de ejecución (thread en ingles). Lo que hace es que el sistema operativo va ejecutando pedasitos de programas por sucesiones cada cierto tiempo de manera rápida.
Un proceso de Unix es un programa en ejecución, independiente de otros procesos, cuando nosotros nos vamos a el terminal y escribimos "ps" nos da una lista de los procesos de ejecución en nuestra maquina. El proceso tiene una parte de memoria propia y esta ejecutandose simultaneamente con otros procesos, por lo tanto no es posible que otro proceso entre a la memoria de otro proceso. por lo tanto por eso unix es un sistema bueno ya que ningún programa que tenga malas intensiones pueden entrar a otro en ejecución incluso ni al propio sistema operativo.
Ahora bien, dentro de un proceso puede que haya varios hilos de ejecución ( o sea varios threads).
Por lo tanto un proceso puede estar haciendo varias cosas a la vez. estos hilos dentro del proceso comparten la misma zona de memoria, por ejemplo si un thread lee una variable, todos los demás del mismo proceso verán el valor de esta variable, por lo tanto cuando hacemos un programa con estas características es indispensable usar mutex (o sea exclusión mutua) para así podemos evitar que haya dos threads al mismo tiempo accedan a la misma estructura de datos, también si un thread se equivoca en algo y estropea la zona de memoria, todos los demás threads vean que esa memoria esta estropeada, por lo tanto un solo fallo en un thread puede fallar a los demás del mismo proceso.
Entonces si hablamos en términos de complejidad, los threads, como comparten memoria y recursos, es obligatorio usar mutex (como había puesto arriba) que son como tipo semáforos, para asi, al momento de emitir un proceso, se haga independiente del de nosotros, para no tener ningún problema, solo que si necesitamos que se comuniquen, lo que necesitariamos es programar memorias compartidas, sockets o mensajes, entre otros.
Ejemplo de como crear threads en C.
Este codigo que encontre en esta pagina es un ejemplo de como crear 2 threads que van a imprimir por la salida estandar, N veces "hola mundo" y M veces "mundo hola"
Para empezar para crear un threads necesitamos la libreria estandar pthreads.h, es parte de gnu library de Linux, nos da el acceso para todas las funciones que empiezen con pthreads_*. En este ejemplo solamente se utilizara pthread_create y pthread_join.
#include <stdio.h>
#include <pthread.h>
#define N 8
#define M 16
const char *mensaje[2] = {"Hola Mundo", "Mundo Hola"};
const int cantidad[2] = {N, M};
void imprime_mensaje(void *ptr);
int main(void)
{
pthread_t hilo0, hilo1;
int id0=0, id1=1;
pthread_create(&hilo0, NULL, (void *) &imprime_mensaje, (void *) &id0);
pthread_create(&hilo1, NULL, (void *) &imprime_mensaje, (void *) &id1);
pthread_join(hilo0, NULL);
pthread_join(hilo1, NULL);
return 0;
}
void imprime_mensaje(void *ptr) {
int i=0, id=0;
id = *(int *) ptr;
for(i=0; i <cantidad[id]; i++)
printf("%s\n",mensaje[id]);
return;
}
Para compilar lo que se hace es incluir la libreria PThread:
mac-rober:~ robertomtz$ gcc -Wall -lpthread -o holaMundo holaMundo.c
Vemos que cuando llamamos a pthread_create esta pasando como una función y necesita varios typecasts (como hable en una entrada anterior que cambia el tipo de dato) para así estar compatible con los tipos de datos que se requieren.
Se definen id0 y id1 con dos contantes, ya que es necesario para pasarle la direccion y no el valor en si.
La función pthread_join, hacen evitar que al terminal el main principal, termine con la vida de los threads. la terminación de un thread es con un return, equivalente a pthread_exit(NULL).
Para concluir, A nosotros como programadores ¿De que nos sirve todo esto?.
Para realizar software de trabajo interactivo, en segundo plano, procesamiento asíncronos, aceleración de la ejecución, y estructuración modular de los programas.
Para la explicación me base en esta y esta pagina
Espero que mi explicación les sirva, si tienen algún comentario acerca de esta entrada, espero me digan ya que estoy abierto a cualquier error.