C++:如何使用thread_local来声明一个指针变量?
Posted
技术标签:
【中文标题】C++:如何使用thread_local来声明一个指针变量?【英文标题】:C++: How to use thread_local to declare a pointer variable? 【发布时间】:2017-09-26 14:59:03 【问题描述】:我试图声明 thread_local 指针变量,然后在一个线程中指向一个新对象。
thread_local static A* s_a = nullptr;
线程销毁时,似乎没有释放新对象的内存。我也尝试使用 unique_ptr,但仍然存在内存泄漏。我正在使用 VS 2015。
这里是代码。在return 0
处添加断点,查看进程的内存,你会看到内存增加了很多。
#include "stdafx.h"
#include <iostream>
#include <thread>
class A
public:
A(const std::string& name) : name_(name) std::cout << (name_ + "::A").c_str() << std::endl;
~A() std::cout << (name_ + "::~A").c_str() << std::endl;
const std::string& name() return name_;
private:
std::string name_;
;
thread_local static std::unique_ptr<A> s_a;
//thread_local static A* s_a = nullptr;
static void test(const std::string& name)
//A a(name);
if(!s_a)
s_a.reset(new A(name));
//s_a = new A(name);
int main()
for (size_t i = 0; i < 10000; i++)
std::thread t0(test, "t0");
std::thread t1(test, "t1");
t0.join();
t1.join();
return 0;
我的问题是如何正确使用thread_local来声明指针变量?
谢谢。
【问题讨论】:
我希望它是一个线程中的单例实例,删除它的时机是什么?为什么使用 unique_ptr 还是内存泄漏? 相关:***.com/questions/17668729/…。还有一个gcc bug report。据说在 4.8.2 中修复。static thread_local unique_ptr
应该可以工作。你怎么知道有泄漏?
我使用的是VS 2015。只需调试并在“return 0;”行停止,在任务管理器中查看进程的内存。
@ldlchina 你是如何确定内存没有释放给进程的内存管理器的?检查任务管理器没有任何好处,因为这将包括已释放给本地内存管理器的内存,因为它仍然属于该进程。我认为您根本没有泄漏,我敢打赌您的输出将证明实际上调用了析构函数。
【参考方案1】:
标准对线程的支持非常基本。
Boost 的跨平台支持当然更胜一筹:
// for thread_specific_ptr
#include <boost/thread/tss.hpp>
// define a deleter for As
void destroy_a(A* ptr) noexcept
delete ptr;
// define the thread_specific pointer with a deleter
boost::thread_specific_ptr<A> s_a &destroy_a ;
static void test(const std::string& name)
// create the object in a manner compatible with the deleter
if(!s_a.get())
s_a.reset(new A(name));
【讨论】:
谢谢,这可能有效,我没有尝试。但由于某种原因,我不能使用 boost.:( 似乎有很多人无法在工作中使用 boost。对我来说,这就像用一条腿走路。真可惜。 对。我同意 boost 非常有用。【参考方案2】:thread_local static std::unique_ptr<A> s_a;
有效。任务管理器中的内存不正确。我用vld来演示内存,没有检测到内存泄漏。
【讨论】:
以上是关于C++:如何使用thread_local来声明一个指针变量?的主要内容,如果未能解决你的问题,请参考以下文章
具有与 std::thread 不同的线程库的 C++ thread_local
C++ 程序结束时的 thread_local 向量分段错误
如何使用 windbg 检查堆转储上的静态 thread_local 变量的内容?
在 Visual Studio 中,与 std::async 一起使用时未调用“thread_local”变量的析构函数,这是一个错误吗?