在向量成员变量中存储线程触发断点
Posted
技术标签:
【中文标题】在向量成员变量中存储线程触发断点【英文标题】:Storing thread in vector member variable triggers breakpoint 【发布时间】:2021-01-06 08:32:40 【问题描述】:我有一个名为 Executor 的类,其中一个 vector
这是我的 Executor.h 代码:
#include <thread>
#include <mutex>
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
class Executor
protected:
vector<thread*> threads;
mutex m;
public:
void submit(const std::function<void()>& f);
Executor();
~Executor();
;
Executor.cpp:
#include "Executor.h"
void Executor::submit(const std::function<void()>& f)
lock_guard<mutex> lock(m);
thread t(f);
threads.push_back(&t);
Executor::Executor()
Executor::~Executor()
for (unsigned int i = 0; i < threads.size(); i++)
threads.at(i)->join();
delete threads.at(i);
threads.clear();
还有main():
Executor ex;
auto fact = []()cout<< "factor(55) = " << factor(55); ;
auto pk = []()cout << "P2(100, 50) = " << P2(100, 50); ;
auto fib = []()cout << "fibonacci(45) = " << fibonacci(45); ;
ex.submit(fact);
ex.submit(pk);
ex.submit(fib);
【问题讨论】:
不能存储指向局部变量的指针 为什么会有一个指向线程的指针向量?这没有任何意义。自己创建一个线程对象向量。 【参考方案1】:在threads.push_back(&t);
中,指针&t
仅在声明t
的范围结束之前有效。这会导致3 个问题:
-
在
submit
内的作用域结束时,线程被破坏而不调用join
,导致std::terminate
被调用
在Executor
的析构函数中,->join
被一个悬空指针调用
在Executor
的析构函数中,你调用delete
来处理没有分配new
的东西
此代码中无需使用指针,如果您将线程直接存储在向量中,您的代码会更简单、更安全:
class Executor
protected:
vector<thread> threads;
mutex m;
public:
void submit(const std::function<void()>& f);
Executor();
~Executor();
Executor(const Executor&) = delete;
Executor& operator=(const Executor&) = delete;
;
void Executor::submit(const std::function<void()>& f)
lock_guard<mutex> lock(m);
threads.emplace_back(f);
Executor::Executor()
Executor::~Executor()
for (auto& thread : threads)
thread.join();
threads.clear();
注意我还删除了复制构造函数和赋值运算符以符合rule of three
【讨论】:
以上是关于在向量成员变量中存储线程触发断点的主要内容,如果未能解决你的问题,请参考以下文章