Multihilo en C – Part 1

 

¿Qué es un hilo? 

Un subproceso es un flujo de secuencia única dentro de un proceso. Debido a que los subprocesos tienen algunas de las propiedades de los procesos, a veces se denominan procesos ligeros

¿Cuáles son las diferencias entre proceso y subproceso? 

Los hilos no son independientes entre sí a diferencia de los procesos. Como resultado, los subprocesos comparten con otros subprocesos su sección de código, sección de datos y recursos del sistema operativo, como archivos abiertos y señales. Pero, al igual que los procesos, un subproceso tiene su propio contador de programa (PC), un conjunto de registros y un espacio de pila. 

¿Por qué multiproceso? Los subprocesos son una forma popular de mejorar la aplicación a través del paralelismo. Por ejemplo, en un navegador, varias pestañas pueden ser hilos diferentes. MS Word usa múltiples subprocesos, un subproceso para formatear el texto, otro subproceso para procesar entradas, etc. 

Los subprocesos funcionan más rápido que los procesos debido a las siguientes razones: 

1) La creación de hilos es mucho más rápida. 

2) El cambio de contexto entre subprocesos es mucho más rápido. 

3) Los hilos se pueden terminar fácilmente 

4) La comunicación entre hilos es más rápida.

 

Consulte http://www.personal.kent.edu/~rmuhamma/OpSystems/Myos/threads.htm para obtener más detalles. 

¿Podemos escribir programas multiproceso en C? 

A diferencia de Java, el lenguaje estándar no admite subprocesos múltiples. POSIX Threads (o Pthreads) es un estándar POSIX para hilos. La implementación de pthread está disponible con el compilador gcc. 

Un programa simple en C para demostrar el uso de las funciones básicas de pthread 

Tenga en cuenta que el siguiente programa puede compilar solo con compiladores C con biblioteca pthread. 

C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>  //Header file for sleep(). man 3 sleep for details.
#include <pthread.h>
 
// A normal C function that is executed as a thread
// when its name is specified in pthread_create()
void *myThreadFun(void *vargp)
{
    sleep(1);
    printf("Printing GeeksQuiz from Thread \n");
    return NULL;
}
  
int main()
{
    pthread_t thread_id;
    printf("Before Thread\n");
    pthread_create(&thread_id, NULL, myThreadFun, NULL);
    pthread_join(thread_id, NULL);
    printf("After Thread\n");
    exit(0);
}

En main(), declaramos una variable llamada thread_id, que es de tipo pthread_t, que es un número entero que se utiliza para identificar el hilo en el sistema. Después de declarar thread_id, llamamos a la función pthread_create() para crear un hilo. 

pthread_create() toma 4 argumentos. 

El primer argumento es un puntero a thread_id que establece esta función. 

El segundo argumento especifica atributos. Si el valor es NULL, se utilizarán los atributos por defecto. 

El tercer argumento es el nombre de la función que se ejecutará para crear el subproceso. 

El cuarto argumento se usa para pasar argumentos a la función myThreadFun. 

La función pthread_join() para subprocesos es el equivalente de wait() para procesos. Una llamada a pthread_join bloquea el subproceso de llamada hasta que finaliza el subproceso con un identificador igual al primer argumento. 

¿Cómo compilar el programa anterior? 

Para compilar un programa multihilo usando gcc, necesitamos vincularlo con la biblioteca pthreads. El siguiente es el comando utilizado para compilar el programa.

gfg@ubuntu:~/$ gcc multithread.c -lpthread
gfg@ubuntu:~/$ ./a.out
Before Thread
Printing GeeksQuiz from Thread 
After Thread
gfg@ubuntu:~/$ 

Programa AC para mostrar múltiples hilos con variables globales y estáticas 

Como se mencionó anteriormente, todos los subprocesos comparten segmento de datos. Las variables globales y estáticas se almacenan en el segmento de datos. Por lo tanto, son compartidos por todos los hilos. El siguiente programa de ejemplo demuestra lo mismo. 

C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
 
// Let us create a global variable to change it in threads
int g = 0;
 
// The function to be executed by all threads
void *myThreadFun(void *vargp)
{
    // Store the value argument passed to this thread
    int *myid = (int *)vargp;
 
    // Let us create a static variable to observe its changes
    static int s = 0;
 
    // Change static and global variables
    ++s; ++g;
 
    // Print the argument, static and global variables
    printf("Thread ID: %d, Static: %d, Global: %d\n", *myid, ++s, ++g);
}
 
int main()
{
    int i;
    pthread_t tid;
 
    // Let us create three threads
    for (i = 0; i < 3; i++)
        pthread_create(&tid, NULL, myThreadFun, (void *)&tid);
 
    pthread_exit(NULL);
    return 0;
}
gfg@ubuntu:~/$ gcc multithread.c -lpthread
gfg@ubuntu:~/$ ./a.out
Thread ID: 3, Static: 2, Global: 2
Thread ID: 3, Static: 4, Global: 4
Thread ID: 3, Static: 6, Global: 6
gfg@ubuntu:~/$ 

Tenga en cuenta que el ejemplo anterior es simple para mostrar cómo funcionan los hilos. Acceder a una variable global en un hilo generalmente es una mala idea. ¿Qué pasa si el subproceso 2 tiene prioridad sobre el subproceso 1 y el subproceso 1 necesita cambiar la variable? En la práctica, si se requiere acceder a la variable global por varios subprocesos, se debe acceder a ellos mediante un mutex. 

Referencias: 

http://www.csc.villanova.edu/~mdamian/threads/posixthreads.html 

Sistemas informáticos: un programador 

Este artículo es una contribución de Rahul Jain . Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *