How to pause a thread?

What is the correct way to pause/suspend a thread?
Thank you

Need some more details. What exactly do you mean by "pause" or "suspend"? Is this action taken from within the thread to be paused it from the parent thread? Does the thread need to "resume" at some point?

There's thread park/unpark, but it's fairly low-level. Rust has plenty of higher-level abstractions built on top of that, like locks, condvars, channels, threadpools and async runtimes.

1 Like

By suspend thread I mean exactly that, suspend its execution, i.e: put it into waiting state.
Yes, thread needs to be resumed at some unspecified point in time (user action).

OK, you've listed them. Could you mind proposing a solution to that particular problem, that is, suspend thread execution and later resume that execution (both actions triggered by the user).
I really don't mean to sound impolite, but listing available things (which btw I am aware of) without even giving a hint to a solution is somewhat irritating to me personally. I apologise if that offends you.

All of these things suspend and resume threads. For them the underlying mechanism is Thread::park and Thread::unpark, but very often it would be a mistake to use these functions directly, since very likely you'd end up reinventing a usage pattern that already has a higher-level equivalent.

You haven't specified your problem precisely enough to recommend any particular solution.

First of all, it depends on how do you want to receive this user input. Thread might be simply blocked on Stdin::read_line, for example, if this fits your pipeline.

Second, no matter how you are receiving the first input (an order to pause), the thread in question must explicitly cooperate to respond on it. You might want, for example, to handle this input externally and to use mpsc-channels (or more efficient crossbeam channels), like this (untested):

// Sender part of channel is held somewhere else, where the input is received.
loop {
    // in real code, you might want to match explicitly, to handle "no messages" and "sender dropped" cases differently
    if receiver.try_recv().is_some() {
        // This line will block the thread until the next message
        receiver.recv().expect("Sender dropped");
    }
    // Do something
}

If your use-case is more complex and this won't work, it seems we have to know more details about it to recommend something.

1 Like

You cannot force another thread to suspend, so you have to ask it to do so, and then the thread can suspend itself. So ultimately it's going to involve some form of message that you communicate to the thread in some manner. For example, you can share an Arc<AtomicBool> with the thread, and the thread checks its value regularly with a loop like this:

while shared_bool.load() {
    std::thread::park();
}

Then you can wake it up again by first setting the boolean back to false, then calling unpark on the suspended thread. Note that the loop is necessary because park is allowed to spuriously wake up at any time.

But there are many variants of this theme. There are also some async-specific solutions, which you should prefer if you are writing async code.

1 Like

In addition to what @Cerberuser already mentioned, you probably want to use some "higher" level thread synchronisation primitives from e.g.

If you choose to use park threads manually, you'll probably end up reimplementing one of those. Channels, condvars, bareerrs, etc are easier to use.

2 Likes

Thanks, clear now.

Thanks for the heads up. Appreciate it.

Thanks, appreciate it.