How to pause thread during blocking operation

There is a thread that is performing long running blocking operation, i.e. copying a very large file.
What would be the sensible way to pause it with the possibility to resume it?

Two options:

  • Check if the OS you are running on has an option to suspend a single thread. This may or may not exist. On Windows there is SuspendThread. On Linux you may be able to create a signal handler pausing the current thread when it receives a certain signal and wake it up again on another signal and then use pthread_kill (if you used pthread_create yourself and have a pthread_t) or kill (if you got the task id through some other way) to send this signal.
  • Split the task in a lot of tiny tasks like say copying 1MB at a time and then check after every task if a pause was requested and use std::thread::park (can spuriously wake up again), a channel or a mutex to pause the thread until it is signaled to continue again.

You would basically have to implement this yourself. There's no way with the standard library type (fs::File, io::copy(), etc).

One way to be to implement the copy yourself. Rather than using io::copy(), write a loop that reads blocks of bytes from the source file, and writes them to the destination file. Then on each iteration of the loop, check for some kind of "paused" event (maybe messages via a mpsc channel, or an Atomic flag, something like that).

Since you presumably want to resume the copy later, when the copy loop is paused, it should go into a state where it waits for the "resume" signal (again, I'd probably use an mpsc channel).

I believe linux (the OS i'm running it on) has that option. But the problem is that if the thread is performing that blocking operation, it will not receive any signals, to the best of my knowledge, but I'm more than happy to be corrected on that. This is the preferred way for me to move forward with this task.

There are two kinds of blocking operations. Interruptable and uninterruptable ones. The former can be interrupted by a signal (returning EINTR once the signal handler is done), while the later can't be interrupted. Writes are of the second category I believe, but generally you only write small chunks at a time even when copying a large file as storing the entire file in memory is not a good idea. Between copying those small chunks a signal can be handled. This won't help when using splice, sendfile or copy_file_range like std::io::copy tries to do though as those allow copying the entire file at once without a large buffer.

I'm using std::fs::copy_file to do copy

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.