Reputation: 1207
I want to have a thread kept as member variable of a class. I want to start the thread inside 'start' method, and stop the thread inside 'stop' method. I also want to be sure that the thread joins, whether or not the 'stop' method is called.
I designed the following code, using shared_ptr
with custom deleter used to both join the thread and delete the pointer to thread, but I am not 100% sure if it is fully correct.
Please comment on this. Is everything OK here? Or maybe there is a better approach how to do this (e.g. use unique_ptr
or desing other RAII class)?
#include <thread>
#include <iostream>
#include <memory>
using namespace std::chrono_literals;
void fun() { std::cout << "inside thread\n"; std::this_thread::sleep_for(1s); }
class A
{
public:
A() : pT(nullptr) {}
void start()
{
std::cout << "starting...\n";
pT.reset(new std::thread(fun), [](auto p) {
if (p->joinable())
{
std::cout << "joining thread\n";
p->join();
}
std::cout << "deleting thread\n";
delete p;
});
}
void stop()
{
std::cout << "stopping...\n";
pT.reset();
}
private:
std::shared_ptr<std::thread> pT;
};
int main()
{
A a;
a.start();
std::this_thread::sleep_for(2s);
a.stop();
return 0;
}
The output is correct:
starting...
inside thread
stopping...
joining thread
deleting thread
Upvotes: 3
Views: 3878
Reputation: 988
In my case i like to have the control of what are create and when it is destroyed. So, my proposal is:
You can add the thread pointer as a member of your class and check if it was finish as i show you in this example:
class A{
std::thread *pThread = nullptr; \\ Thread Pointer
//...
public:
A();
~A();
void start();
void stop();
}
And used it as:
void start()
{
if(pThread == nullptr)
{
pThread = new thread(fun); //Create the thread and store its reference
}
}
~A()
{
if (pThread != nullptr)
{
if(pThread->joinable()) \\Wait until the thread has been finished
pThread->join();
delete pThread; \\IMPORTANT, release the memory.
}
}
In this sample i use the thread to synchronized the destruction of Class, it will not be destroyed until the thread has been finished.
Note: If you want to use a method of some class as the function which runs the thread, you can use std::bind
.
Also you can use smart pointer as
unique_ptr
instead ofstd::thread
, as i made in this sample. In this case the memory will be release when the class get to be destroyed, so be sure the thread is finished before delete this pointer o leave the context (Class).
Upvotes: 3