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&lt;A&gt; s_a; 有效。任务管理器中的内存不正确。我用vld来演示内存,没有检测到内存泄漏。

【讨论】:

以上是关于C++:如何使用thread_local来声明一个指针变量?的主要内容,如果未能解决你的问题,请参考以下文章

具有与 std::thread 不同的线程库的 C++ thread_local

C++ 程序结束时的 thread_local 向量分段错误

走进C++11(四十五) thread_local

如何使用 windbg 检查堆转储上的静态 thread_local 变量的内容?

在 Visual Studio 中,与 std::async 一起使用时未调用“thread_local”变量的析构函数,这是一个错误吗?

销毁 thread_local 对象