Usar la biblioteca de subprocesos C11 en C

Jinku Hu 12 octubre 2023
  1. Utilice la función thrd_create para crear un nuevo hilo y ejecutar la rutina dada en C
  2. Utilice la función thrd_join para esperar el hilo dado en C
Usar la biblioteca de subprocesos C11 en C

Este artículo explicará varios métodos de cómo utilizar la biblioteca de subprocesos C11 en C.

Utilice la función thrd_create para crear un nuevo hilo y ejecutar la rutina dada en C

La compatibilidad con subprocesos se ha retrasado durante mucho tiempo en la especificación del lenguaje C estándar, y finalmente se realizó en C11. Antes de eso, la API de subprocesos POSIX se utilizó como la herramienta principal para utilizar la programación de subprocesos múltiples. Dado que el C11 proporcionó una interfaz más estándar que podría usarse sin dependencias de plataforma, se ha recomendado usar la API de lenguaje ISO que la versión POSIX. Aunque las dos API no coinciden en sus prototipos de funciones, las características principales son en su mayoría similares. En el siguiente ejemplo, demostramos el escenario simple donde se inician cuatro hilos para ejecutar la función printHello y luego terminan sin unirse al hilo principal.

thrd_create toma tres argumentos,

  1. El primero es un puntero al identificador del hilo.
  2. El segundo argumento es de tipo - thrd_start_t, que es simplemente typedef para un prototipo de puntero de función.
  3. El tercer parámetro especifica un argumento que se puede pasar a la función.

Los códigos de estado de retorno de thrd_create se definen utilizando los valores de enum: thrd_success, thrd_nomem y thrd_error.

#include <stdio.h>
#include <stdlib.h>
#include <threads.h>
#include <unistd.h>

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

void *printHello(void *thr_id) {
  long tid;
  tid = (long)thr_id;
  printf("Hello There! thread #%ld, pthread ID - %lu\n", tid, thrd_current());
  thrd_exit(EXIT_SUCCESS);
}

int main(int argc, char const *argv[]) {
  thrd_t threads[NUM_THREADS];
  int rc;
  long t;

  for (t = 0; t < NUM_THREADS; t++) {
    rc = thrd_create(&threads[t], (thrd_start_t)printHello, (void *)t);
    if (rc == thrd_error) {
      printf("ERORR; thrd_create() call failed\n");
      exit(EXIT_FAILURE);
    }
  }
  thrd_exit(EXIT_SUCCESS);
}

Producción :

Hello There! thread 0, pthread ID - 140215498864384
Hello There! thread 1, pthread ID - 140215490471680
Hello There! thread 3, pthread ID - 140215473686272
Hello There! thread 2, pthread ID - 140215482078976

Utilice la función thrd_join para esperar el hilo dado en C

thrd_join es un análogo de la función pthread_join, y bloquea el hilo actual hasta que el hilo dado finaliza la ejecución. Toma dos argumentos: identificador de hilo y puntero int que denota la ubicación donde el código de estado de retorno se puede almacenar opcionalmente si el usuario proporciona la dirección válida. Si se llama a thrd_join en un hilo que ya estaba separado o unido, el resultado es un comportamiento indefinido. La función devuelve los valores correspondientes a thrd_success o thrd_error.

El siguiente código de ejemplo implementa el escenario donde cuatro subprocesos incrementan la variable de tipo atomic_int. Finalmente, el hilo principal que espera a que otros terminen imprime el valor de suma final de counter.

#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <threads.h>
#include <unistd.h>

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

atomic_int counter = 0;

enum { MAX_ITER = 1000 };

void *printHello(void *thr_id) {
  long tid;
  tid = (long)thr_id;
  printf("thread %ld started incrementing ID - %lu\n", tid, thrd_current());

  for (int i = 0; i < MAX_ITER; ++i) {
    counter += 1;
  }

  return NULL;
}

int main(int argc, char const *argv[]) {
  thrd_t threads[NUM_THREADS];
  int rc;
  long t;

  for (t = 0; t < NUM_THREADS; t++) {
    rc = thrd_create(&threads[t], (thrd_start_t)printHello, (void *)t);
    if (rc == thrd_error) {
      printf("ERORR; thrd_create() call failed\n");
      exit(EXIT_FAILURE);
    }
  }

  for (t = 0; t < NUM_THREADS; t++) {
    thrd_join(threads[t], NULL);
  }
  printf("count = %d\n", counter);

  thrd_exit(EXIT_SUCCESS);
}

Producción :

thread 0 started incrementing ID - 139729818216192
thread 2 started incrementing ID - 139729801430784
thread 3 started incrementing ID - 139729793038080
thread 1 started incrementing ID - 139729809823488
count = 4000
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artículo relacionado - C Thread