Angel Angel
Angel Angel

Reputation: 21746

Is it possible to force resume a sleeping thread?

Is it possible to force resume a sleeping thread which has been paused? For example, by calling sleep:

std::thread::sleep(std::time::Duration::from_secs(60 * 20));

I know that I can communicate between threads using std::sync::mpsc but if the thread is asleep, this does not force it to wake up before the time indicated.

I have thought that using std::sync::mpsc and maybe Builder and .name associated with the thread, but I do not know how to get the thread to wake up.

Upvotes: 2

Views: 1108

Answers (2)

the8472
the8472

Reputation: 43150

park_timeout allows timed sleeps with wakeups from unpark, but it can also wake up early.

See std::thread module documentation

Upvotes: 1

Lukas Kalbertodt
Lukas Kalbertodt

Reputation: 88986

If you want to be woken up by an event, thread::sleep() is not the correct function to use, as it's not supposed to be stopped.

There are other methods of waiting while being able to be woken up by an event (this is usually called blocking). Probably the easiest way is to use a channel together with Receiver::recv_timeout(). Often it's also sufficient to send () through the channel. That way we just communicate a signal, but don't send actual data.

If you don't want to wake up after a specific timeout, but only when a signal arrives, just use Receiver::recv().


Example with timeout:

use std::thread;
use std::sync::mpsc::{self, RecvTimeoutError};
use std::time::Duration;
use std::io;

fn main() {
    let (sender, receiver) = mpsc::channel();

    thread::spawn(move || {
        loop {
            match receiver.recv_timeout(Duration::from_secs(2)) {
                Err(RecvTimeoutError::Timeout) => {
                    println!("Still waiting... I'm bored!");
                    // we'll try later...
                }
                Err(RecvTimeoutError::Disconnected) => {
                    // no point in waiting anymore :'(
                    break;
                }
                Ok(_) => {
                    println!("Finally got a signal! ♥♥♥");
                    // doing work now...
                }
            }
        }
    });

    loop {
        let mut s = String::new();
        io::stdin().read_line(&mut s).expect("reading from stdin failed");
        if s.trim() == "start" {
            sender.send(()).unwrap();
        }
    }
}

Here, the second thread is woken up at least every two seconds (the timeout), but also earlier once something was sent through the channel.

Upvotes: 6

Related Questions