es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo realizo una suspensión interrumpible en Rust?

Estoy escribiendo un programa en Rust que realiza una acción cada 2 segundos. El programa también utiliza la biblioteca ctrlc para manejar interrupciones. Sin embargo, en algunos casos, tengo que esperar hasta 2 segundos para matar el proceso. Estoy usando la función predeterminada std::thread::sleep, que aparentemente no puede ser interrumpida.

Aquí viene mi pregunta. ¿Es posible que mi programa duerma de manera interrumpible? En otras palabras, ¿tiene Rust una función predeterminada para interrumpir un programa que está durmiendo? Sé que en C se interrumpe automáticamente cualquier función de espera cuando se recibe la señal SIGINT.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible hacer que el programa Rust duerma de manera interrumpible. Rust proporciona una función integrada park_timeout() en el módulo std::sync::Arc, que se puede utilizar para estacionar el hilo por una cantidad determinada de tiempo y se puede interrumpir enviando una señal al hilo. Esto se puede usar en lugar de std::thread::sleep() para hacer que el sueño sea interrumpible. Aquí hay un ejemplo de cómo implementar esto:

    use std::sync::{Arc, Mutex};
    use std::thread;
    use std::time::Duration;
    
    fn main() {
        let running = Arc::new(Mutex::new(true));
        let running_clone = running.clone();
    
        ctrlc::set_handler(move || {
            *running_clone.lock().unwrap() = false;
        })
        .expect("Error setting Ctrl-C handler");
    
        while *running.lock().unwrap() {
            // Dormir por dos segundos
            match Arc::new(thread::current()).park_timeout(Duration::from_secs(2)) {
                Ok(_) => break,
                Err(parker) => {
                    // Interrumpido, así que continuar el bucle
                    parker.unpark();
                }
            }
    
            // Realizar acción después de dormir
            println!("Acción realizada después de dormir");
        }
    }
    

    En este ejemplo, primero creamos un objeto running Arc que se comparte entre el hilo principal y el cierre manejador de señales. También creamos un clon de este objeto para usarlo en el cierre manejador de señales.

    En el bucle principal, utilizamos la función park_timeout() para estacionar el hilo durante dos segundos. Si el hilo se desestaciona antes del tiempo de espera, continuamos el bucle y no realizamos la acción después del sueño. Si se produce el tiempo de espera, realizamos la acción después de dormir.

    En el cierre manejador de señales, establecemos el valor de running_clone en falso para salir del bucle principal y salir del programa.

    Al utilizar la función park_timeout() en lugar de sleep(), hacemos que el sueño del programa sea interrumpible y capaz de manejar señales como SIGINT de manera eficiente.

Comments are closed.