c++ - 多线程时不断调用对象析构函数,但对象没有超出范围
问题描述
我不知道为什么即使我调用了对象的成员函数,即使它仍然在它的范围内,仍然调用了析构函数。一个简单的例子如下所示:
#include<thread>
#include<iostream>
class Obj1
{
private:
public:
~Obj1();
void testFunc();
};
Obj1::~Obj1()
{
std::cout<<"destory\n";
}
void Obj1::testFunc(){
std::cout<<"testfun\n";
}
#include "Obj1.hpp"
#include <thread>
#include <chrono>
int main()
{
using namespace std::chrono_literals;
Obj1 obj1 = Obj1();
for(int i=0;i<100;i++){
std::thread th = std::thread(&Obj1::testFunc,obj1);
std::this_thread::sleep_for(1s);
std::cout<<"we wait\n";
}
}
当我尝试运行它时,我可以看到输出:
destory
testfun
destory
we wait
terminate called without an active exception
Aborted (core dumped)
我想知道为什么每次线程结束时 obj1 都会被销毁?ps延迟1s的原因是因为这是在实时系统中使用的,主循环的频率较低,任务将在下一个循环之前完成。
解决方案
代码中的两个最大问题:
- 您正在为每次
std::thread
启动制作副本。 - 你不是在等待你的线程终止。
Astd::thread
需要一个可调用的参数,如果需要,还需要适当的参数。在您的情况下,可调用对象是指向成员函数的指针,它需要一个对象实例或地址(std::thread
将使用其中任何一个)。您通过复制. obj1
如果意图是让所有线程访问同一个对象,则应改为传递地址。
然后等待线程终止,当然
代码(添加消息以检测复制构造)
#include <iostream>
#include <vector>
#include <thread>
class Obj1
{
public:
Obj1() { std::cout << "construct\n"; }
Obj1(const Obj1&) { std::cout << "copy\n"; }
~Obj1() { std::cout << "destroy\n"; }
void testFunc();
};
void Obj1::testFunc() {
std::cout << "testfun\n";
}
int main()
{
Obj1 obj1;
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i)
threads.emplace_back(&Obj1::testFunc, &obj1); // <<== HERE
for (auto& t : threads)
t.join();
}
输出(可能会有所不同)
construct
testfun
testfun
testfun
testfun
testfun
testfun
testfun
testfun
testfun
testfun
destroy
推荐阅读
- c# - 在静态类中配置静态 StreamWriter
- flutter - 如何在 Flutter 中制作弧形底部 appBar?
- html - 仅使用 `direction: rtl` 样式化元素
- javascript - 可以对字符串数组进行编码吗?
- javascript - 如何从 gulp src 流中排除所有 node_modules 目录?
- r - 从具有未知数量参数的模型动态构建表达式以获得相当的标签
- flutter - 颤动如何使用共享首选项保存动态列表?
- python - 更改 ylabel matplotlib 上的刻度大小
- elasticsearch - Elasticsearch-oss 不能同时绑定本地和外部地址
- mysql - 如何从 1 字段为最大值或最小值的表中选择行?