Creación de hilos con Rust

Clase 7 de 12Curso de Gestión de Servidores con Rust

En la clase anterior vimos cómo se maneja la concurrencia en Rust, abordamos que para mejor manejo de errores es dividir el código en multiprocesos o hilos. En esta clase veremos cómo podemos crear hilos, moverlos y la comunicación entre ellos.

NOTA: En cada segmento de código, si hay una palabra que diga Ejecutar podrás darle clic e ir directamente a Rust Playground para que puedas probar el código.

Creando un hilo (thread)


Para comenzar a crear un hilo, comenzaremos nuestro código invocando el módulo std::thread, nos permitirá usar todos sus métodos y funciones que nos facilitan la creación de hilos, veamos un ejemplo.

use std::thread; fn main() { let example = thread::spawn(move || { println!("Hola desde tu primer hilo"); }); let _ = example.join(); }

Ejecutar

Este ejemplo lo habrás visto en temas más básicos de Rust, pero expliquemos un poco de qué es lo que está pasando.

Primero creamos una variable llamada example donde nos permite traer la función thread::spawn. Spawn es una función genérica con un argumento y dos parámetros de tipo:

fn spawn<F, T>(f: F) -> JoinHandle<T>
  1. El tipo F puede ser cualquier función / cierre que devuelva un T ( FnOnce() -> T), se puede transferir de forma segura entre subprocesos ( Send) y no contiene referencias de corta duración ( 'static),
  2. El tipo T puede ser de cualquier tipo, siempre que se pueda transferir entre subprocesos y no contenga referencias de corta duración.

El JoinHandle<T> permite recuperar el T que f regresa, a través de su método join.

El move es un cierre de hilos que a menudo se usa junto a thread::spawn porque le permite usar datos de un hilo en otro hilo.

También puedes agregar:

thread::sleep_ms(1000);

Las llamadas thread::sleep obligan a un subproceso a detener su ejecución durante un período breve, lo que permite que se ejecute un subproceso diferente. Los subprocesos probablemente se turnen, pero eso no está garantizado: depende de cómo su sistema operativo programe los subprocesos.

Veamos un segundo caso:

use std::thread; use std::time::Duration; fn main() { let handle = thread::spawn(|| { for i in 1..10 { println!("hola {} desde el primer hilo", i); thread::sleep(Duration::from_millis(1)); } }); handle.join().unwrap(); for i in 1..5 { println!("hola {} desde el segundo hilo", i); thread::sleep(Duration::from_millis(1)); } for i in 1..4 { println!("hola {} desde el tercer hilo", i); thread::sleep(Duration::from_millis(1)); } }

Ejecutar

El ejemplo imprime un texto de un hilo principal y otro texto de un hilo nuevo. Ten en cuenta que con esta función, el nuevo subproceso se detendrá cuando finalice el subproceso principal, haya terminado o no de ejecutarse. El resultado de este programa puede ser un poco diferente cada vez.

En este segundo caso agregamos el método Duration qué es un tipo de duración para representar un lapso de tiempo, generalmente utilizado para tiempos de espera del sistema.

Hasta aquí, hemos visto lo básico de crear hilos con Rust. Ahora inténtalo, crea diferentes tipos de hilos, usa thread::sleep para que se detenga cierto tiempo y se ejecute el siguiente hilo, muestra tus resultados en los comentarios.