这种创建带有指向实例的指针的分离 std::thread 的方式是错误的吗?
Is this way of creating detached std::thread with pointer to instance wrong?
我遇到过一些类,它们的唯一功能是在循环中连续执行一些工作,它们的设计使得它们定义了一个公共方法,可以调用该方法以在新std::thread
中调用此成员函数。我指的是这样的东西:
class ThreadLooper {
public:
ThreadLooper(const std::string &thread_name)
: thread_name_{thread_name}, loopCounter_{0} {}
~ThreadLooper() {
cout << thread_name_ << ": destroyed and counter is " << loopCounter_
<< std::endl;
}
void run() {
std::thread([this]() { detachedThreadLoop(); }).detach();
}
private:
void detachedThreadLoop() {
cout << thread_name_ << ": detachedThreadLoop() started running"
<< std::endl;
while (true) {
using namespace std::literals::chrono_literals;
std::this_thread::sleep_for(2s);
++loopCounter_;
cout << thread_name_ << ": counter is " << loopCounter_ << std::endl;
}
}
std::string thread_name_;
std::atomic_uint64_t loopCounter_;
};
int main() {
cout << "In main()" << std::endl;
{
ThreadLooper threadLooper{"looper1"};
threadLooper.run();
using namespace std::literals::chrono_literals;
std::this_thread::sleep_for(20s);
cout << "main() done sleeping, exiting block scope..." << std::endl;
}
while (true) {
using namespace std::literals::chrono_literals;
std::this_thread::sleep_for(20s);
cout << "main() woke up..." << std::endl;
}
return 0;
}
似乎因为在分离的线程中运行的函数具有指向实例的指针,但可以在该实例的生存期之后继续运行,这很糟糕。我见过其他类,其中线程没有分离,然后在析构函数中设置了一个标志来告诉线程循环退出,然后将线程加入析构函数中。似乎后者是执行此操作的正确方法,并且前者依赖于这样一个事实,即该类仅在其实例在程序持续时间内存在的情况下使用。这是正确的还是我错过了什么?
是的,使用 std::thread::detach
意味着您需要有自己的方法来确保线程在销毁它使用的所有资源之前终止。
在这种情况下,当程序退出main()
中的第一个块范围时,ThreadLooper
将调用未定义的行为。最好不要使用 detach()
然后std::thread
如果你忘记在线程(及其包含对象)被销毁之前调用join()
,它将调用std::terminate
。
相关文章:
- 如何在c++中为模板函数实例创建快捷方式
- 在c代码之间共享数据的最佳方式
- 在C++中将函数压缩为两种方式
- 以螺旋方式打印矩阵的程序.(工作不好)
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 创建引用向量的优雅方式
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 在std::thread中,joinable()然后join()线程安全吗
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 不同/较旧的处理器运行c++代码的方式是否不同
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 重载方法的方式会在使用临时调用时生成编译器错误
- 在reactor中存储eventHandlers的最佳方式是什么
- 如何以优化的方式同时迭代两个间距不相等的数组
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 分离一个静态常量 std::thread?
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 尝试使用 std::vector<std::thread时出现静态断言失败错误>
- 这种创建带有指向实例的指针的分离 std::thread 的方式是错误的吗?