我希望将一个线程保存为类的成员变量。我想在内部启动线程' start'方法,并停止内部的线程'停止'方法。我也想确保线程加入,无论是否停止'方法被调用。
我设计了以下代码,使用shared_ptr
自定义删除器用于连接线程并删除指向线程的指针,但我不是100%确定它是否完全正确。
请对此发表评论。一切都好吗?或者可能有更好的方法如何做到这一点(例如使用unique_ptr
或设计其他RAII类)?
#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;
}
输出正确:
starting...
inside thread
stopping...
joining thread
deleting thread
答案 0 :(得分:0)
在我的情况下,我喜欢控制什么是创造以及什么时候被摧毁。所以,我的建议是:
您可以将线程指针添加为类的成员,并检查它是否已完成,因为我在此示例中显示:
class A{
std::thread *pThread = NULL; \\ Thread Pointer
//...
public:
A();
~A();
void start();
void stop();
}
并将其用作:
void start()
{
if(pThread == NULL)
{
pThread = new thread(fun); //Create the thread and store its reference
}
}
~A()
{
if (pThread != NULL)
{
if(pThread->joinable()) \\Wait until the thread has been finished
pThread->join();
delete pThread; \\IMPORTANT, release the memory.
}
}
在这个示例中,我使用线程来同步Class的销毁,在线程完成之前不会销毁它。
注意:如果要将某个类的方法用作运行该线程的函数,可以使用std::bind
。
此外,您可以将智能指针用作
unique_ptr
而不是std::thread
,就像我在此示例中所做的那样。在这种情况下,当类被销毁时,内存将被释放,因此请确保在删除此指针之前完成线程o离开上下文(Class)。