2017-09-26 4 views
0

J'ai essayé de déclarer la variable de pointeur thread_local, puis de pointer vers un nouvel objet dans un thread.C++: Comment utiliser thread_local pour déclarer une variable pointeur?

thread_local static A* s_a = nullptr; 

Semblait la mémoire du nouvel objet n'a pas été libéré lorsque le fil détruit. J'ai également essayé d'utiliser unique_ptr, mais toujours fuite de mémoire. J'utilise VS 2015.

Voici le code. Ajouter un point de rupture à return 0, vérifiez la mémoire du processus, vous verrez la mémoire augmente beaucoup.

#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; 
} 

Ma question est de savoir comment utiliser thread_local pour déclarer une variable de pointeur manière correcte?

Merci.

+0

Je voudrais que ce soit une instance singleton dans un thread, quel est le timing pour le supprimer? pourquoi utiliser unique_ptr fuite de mémoire encore? – ldlchina

+1

Pertinent: https://stackoverflow.com/questions/17668729/memory-leak-in-gcc-4-8-1-when-using-thread-local. Et un [rapport de bug gcc] (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57914). Censément fixé en 4.8.2. – AMA

+1

'static thread_local unique_ptr' devrait fonctionner. Comment savez-vous qu'il y a une fuite? – rustyx

Répondre

0

Les thread_local static std::unique_ptr<A> s_a; œuvres. La mémoire dans le gestionnaire de tâches n'est pas vraie. J'ai utilisé vld pour démontrer la mémoire, Aucune fuite de mémoire détectée.

1

Le support de la norme pour le filetage est extrêmement basique.

soutien multi-plateforme de Boost est bien sûr supérieure:

// 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)); 
    } 
} 
+0

Merci, cela peut fonctionner, je n'ai pas essayé. Mais pour une raison quelconque, je ne peux pas utiliser boost. :( – ldlchina

+1

Tant de gens semblent être empêchés d'utiliser boost dans leur travail.Pour moi, cela ressemble à marcher avec une jambe.Il est une honte. –

+0

Droite.Je suis d'accord boost est très utile . – ldlchina