如何在C++智能指针中放置线程
How do I put a thread in a C++ smart pointer?
我想创建一个C++类,线程每分钟做一次工作。
首先,我可以将线程定义为变量成员吗?
class my_class
{
public:
my_class()
: my_thread_(task, this)
{
}
~my_class()
{
done_ = true;
}
void run()
{
while(!done_)
{
...do work in the thread...
}
}
private:
static task(my_class * ptr)
{
ptr->run();
}
std::thread my_thread_;
std::atomic<bool> done_ = false;
};
其次,我可以改用带有线程的智能指针吗?
class my_class
{
public:
~my_class()
{
done_ = true;
}
void init()
{
my_thread_.reset(new std::thread(task, this));
}
void run()
{
while(!done_)
{
...do work in the thread...
}
}
private:
static task(my_class * ptr)
{
ptr->run();
}
std::unique_ptr<std::thread> my_thread_;
std::atomic<bool> done_ = false;
};
在我看来,我需要先加入子线程才能销毁它,但我想知道 std::thread 的析构函数是否知道安全地执行此操作。
你可以把std::thread
放在任何你想要的地方,它们并不特别。销毁线程句柄是有问题的。你可以隐式分离、隐式终止或隐式加入,每个选项都是不好的。 std::~thread
(通常)只是杀死整个程序。防止join
或detach
它。
由于您似乎想要隐式加入,因此您可能希望使用std::async
(可能使用 std::launch::async
策略)来启动线程。它返回一个析构函数隐式联接的std::future
。
可以
创建std::unique_ptr<std::thread>
.它将调用 std::thread 析构函数,当unique_ptr范围结束时。请记住,调用 std::thread 析构函数并不是轻轻地终止运行,而是通过 std::terminate
终止运行。要正常结束 std::thread,您必须在 std::thread 对象上运行.join()
。
根据 cppreference.com,
线程对象没有关联的线程(并且可以安全地 销毁)之后
- 它是默认构造的
- 它已从
- join() 已被调用
- 分离() 已被调用
因此,如果您将线程定义为成员变量并像这样编写析构函数:
~my_class()
{
done_ = true;
my_thread_.join();
}
一切都很好,因为标准保证std::thread
析构函数只会在my_class
析构函数之后调用,请参阅此问答。
相关文章:
- 如何检索指向在单独线程上运行的函数的移动指针?
- 如何将'this'指针传递给C++ WinAPI 线程?
- 从子线程访问指针
- 将字符串指针传递到C++和Xcode 11.1中不同线程上运行的函数
- 通过std::shared_ptr使用Rcpp和RcppParallel的线程安全函数指针
- 在多线程函数中返回共享的常量指针会导致计时问题吗?
- 线程中的成员函数指针
- 如何安全地终止线程?(使用指针)C++
- 指向成员对象的指针 - 中断线程
- 是否可以访问非线程安全容器内指针指向的值(线程安全映射中的条目)?
- 如何抓取指向Qt中弹出对话框的指针,该对话框阻止了QTest中的UI线程
- 将指针传递到另一个线程的正确方法
- CPP:如何使用需要指针的方法创建线程
- 启动线程会导致指针初始化时出现分段错误
- 是否访问指针元组和互斥锁线程安全
- 在容器中存储指向对象的指针时的线程安全
- 将线程指针绑定到对象时错误
- 如何安全地删除析构函数中的线程指针
- 删除 std::线程指针会引发异常"libc++abi.dylib: terminating"
- 线程指针和函数指针