在C ++ - C ++ / CLI环境中泄漏std :: shared_ptr thread_local变量

时间:2018-01-24 16:05:14

标签: c++ multithreading web-services wcf c++-cli

所以我有这个WCF webservice服务器,其中一个web服务是用C ++ / CLI编写的。 webservice方法只是一个存根。它用于调用本机C ++有用的代码。

在有用的C ++代码中,我有这个thread_local std :: shared_ptr变量。它是在Web服务调用的方法中分配的。

thread_local std::shared_ptr<MyClass> leaking(new MyClass());

问题是:我的变量永远不会被释放。析构函数永远不会被调用。 我正在使用Microsoft C ++ 14.0 64位编译器编译我的代码。

我的问题是:thread_local支持和Microsoft编译器有一些奇怪的限制吗?

我无法在MSDN上找到任何内容。

我尝试了什么:

我知道WCF使用.NET线程池来处理Web服务请求。我在某处读到.Net线程在其生命周期内不能保证映射到同一本机线程。但是,在当前实现中,.Net线程 以1对1映射到同一本机线程。

我尝试在进程退出之前枚举活动线程,并且只有进程主线程处于活动状态。

修改:

我刚刚在MSDN上找到了这个:

  

无法使用thread属性声明自动数据对象。

Link to MSDN

然而,这似乎只适用于微软的线程&#39;修改。编译确实显示了&#39;线程&#39;但没有使用&#39; thread_local&#39;所以我想这不能解决我的问题。

2 个答案:

答案 0 :(得分:2)

  

6.7.2线程存储持续时间。

     

使用 thread_local 关键字声明的所有变量都具有线程存储持续时间。这些实体的存储应持续创建它们的线程的持续时间。每个线程有一个不同的对象或引用,声明的名称的使用是指与当前线程关联的实体。

     

具有存储持续时间的变量应在其第一次使用odr(6.2)之前初始化,如果构造,则应在线程退出时销毁。

答案 1 :(得分:1)

shared_ptr不是灵丹妙药。它只会在分配其他内容时删除其内容。根据您的评论,一旦分配,您似乎永远保留它。因此,它不会按设计删除对象。

我想象的场景与:

相同
#include <memory>
#include <iostream>
#include <thread>

class Foo
{
public:
    ~Foo() { std::cout << "Deleted" << std::endl;}
};

thread_local std::shared_ptr<Foo> f;

void t()
{
    f = std::shared_ptr<Foo>(new Foo);
}

int main()
{
    std::thread thread(t);
    thread.detach();
}