I am using an std::thread in my C++ code to run a function. I would like to be able to start the function, and pause it and resume it at will from another thread. This is how the starting and pause/resume is meant to work:
Task task(&myFun);
task.start(); // this starts the function myFun
task.pause(); // this pauses the function myFun wherever it's at
task.resume(); // this resumes myFun at the point where it paused
task.stop(); // this indefinitely stops myFun
Here is the class declaration:
class Task {
public:
Task(std::function<void()> func);
void start();
void pause();
void resume();
void stop();
private:
std::string status;
std::function<void()> fun;
std::mutex m;
std::condition_variable condVar;
std::thread taskThread;
};
With the constructor being:
Task(F func) : fun(std::move(func)) {
this->status = "paused";
}
Here is my current implementation of the scheduling, pausing, resuming and stopping methods:
void start() {
status = "running";
taskThread = std::thread([this]{
for (;;) {
std::unique_lock<decltype(this->m)> l(this->m);
this->condVar.wait(l, [this]{ return status == "running"; });
fun();
status = "completed";
}
});
}
void pause() {
if(status == "running") {
{
std::lock_guard<decltype(this->m)> l(this->m);
status = "paused";
}
this->condVar.notify_one();
}
}
void resume() {
if(status == "paused") {
{
std::lock_guard<decltype(this->m)> l(this->m);
status = "running";
}
this->condVar.notify_one();
}
}
void stop() {
if (status == "running" or status == "paused") {
{
std::lock_guard<decltype(this->m)> l(this->m);
status = "stopped";
}
this->condVar.notify_one();
}
}
My current implementation allows for the function fun to be started and completed with the correct "running" and "completed" flags. However, when I try to pause, the method pause()
waits at the line std::lock_guard<decltype(this->m)> l(this->m);
until myFun
is completed, and then changes the status of task
.
My question is: in C++, is there a way to pause the thread while myFun
is running, hence pausing / resuming myFun
?
Aucun commentaire:
Enregistrer un commentaire