2013-10-17 33 views
13

Makro aracılığıyla erişilecek her iş parçacığı için benzersiz bir işaretçi kaydetmem gerekiyor. Bunu bir tekil ve statik thread_local std :: unique_ptr nesneleriyle çözmem gerektiğini düşündüm. İşte kod basitleştirilmiş bir versiyonudur:C++ 11: GCC 4.8 static thread_local std :: unique_ptr tanımsız başvuru

main.cpp

#include <thread> 
#include <vector> 
#include <iostream> 
#include <mutex> 
using namespace std; 

#include "yay.hpp" 

mutex coutMutex; 

void yay(int id) 
{ 
    int* yayPtr = getYay(); 

    // I know this is bad 
    coutMutex.lock(); 
    cout << "Yay nr. " << id << " address: " << yayPtr << endl; 
    coutMutex.unlock(); 
} 

int main() 
{ 
    vector<thread> happy; 
    for(int i = 0; i < thread::hardware_concurrency(); i++) 
    { 
     happy.push_back(thread(yay, i)); 
    } 

    for(auto& smile : happy) 
    { 
     smile.join(); 
    } 
    return 0; 
} 

yay.hpp

#ifndef BE_HAPPY 
#define BE_HAPPY 

#include <memory> 
class Yay 
{ 
    private: 
     static thread_local std::unique_ptr<int> yay; 
     Yay() = delete; 
     Yay(const Yay&) = delete; 
     ~Yay() {} 
    public: 
     static int* getYay() 
     { 
      if(!yay.get()) 
      { 
       yay.reset(new int); 
      } 
      return yay.get(); 
     } 
}; 

#define getYay() Yay::getYay() 

#endif 

yay.cpp

#include "yay.hpp" 

thread_local std::unique_ptr<int> Yay::yay = nullptr; 

Ben gcc 4.8 ile bu derleme .1:

g++ -std=c++11 -pthread -o yay main.cpp yay.cpp 

alıyorum:

/tmp/cceSigGT.o: In function `_ZTWN3Yay3yayE': 
main.cpp:(.text._ZTWN3Yay3yayE[_ZTWN3Yay3yayE]+0x5): undefined reference to `_ZTHN3Yay3yayE' 
collect2: error: ld returned 1 exit status 

Ben ancak clang 3.4 ile mükemmel çalışıyor, ben clang daha fazla bilgi alabilirsiniz umuyordum:

clang++ -std=c++11 -pthread -o yay main.cpp yay.cpp 

Ve programını çalıştıran bekliyordum sonucu verir :

Yay nr. 2 address: 0x7fcd780008e0 
Yay nr. 0 address: 0x7fcd880008e0 
Yay nr. 1 address: 0x7fcd800008e0 
Yay nr. 3 address: 0x7fcd700008e0 
Yay nr. 4 address: 0x7fcd740008e0 
Yay nr. 5 address: 0x7fcd680008e0 
Yay nr. 6 address: 0x7fcd6c0008e0 
Yay nr. 7 address: 0x7fcd600008e0 

Ben statik thread_local unique_ptr obj sahip olmamak mümkün, burada yanlış yapıyorum emin değilim ECTS? Int veya 'naked' işaretçileri gibi basit tiplerle çalışır.

Düzenleme:

Bu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55800

EDIT2 ilgili bir hata olduğunu mümkündür:

Çözüm 1: clang bir dosya derlemek (yay.cpp)

Geçici çözüm 2 (korkunç ve okunamayan): derleme yay.cpp derlemeye derleme, ekleme

montaj dosyasına

, dosyayı nesne derlemek, ben Yay.hpp içinde Yay için do-nothing ctor tanımlayarak bu deneyler kalan

+0

Önişlemci 'getYay()' ifadesinin değiştirilmesi sizi rahatsız ediyor mu? – Tom

+0

Hayır, #define'ı kaldırır ve Yay :: getYay() 'ı doğrudan çağırırsam işe yaramaz. – linedot

+0

Hata raporunuzda, kodunuzun çok daha küçük bir sürümünü ve olası bir geçici çözümü görebilirsiniz. Belki bunu bir cevap olarak gönderebilirsiniz. –

cevap

2

ile bağlantı:

 
- Yay() = delete; 
+ Yay() {} 

Bunu yaptığında, hata mesajı oldu: GCC bug 55800 götürdü

 
/tmp/cc8gDxIg.o: In function `TLS wrapper function for Yay::yay': 
main.cpp:(.text._ZTWN3Yay3yayE[_ZTWN3Yay3yayE]+0x5): undefined reference to `TLS init function for Yay::yay' 

. Hata, 4.8.2'den GCC sürümlerinde mevcut ve 4.8.3 ve 4.9'da sabitlenmiştir. Ben yinelenen GCC bug 59364 üzerinde bulduğum tartışma konuları, karar düzeltme noktası geri port için yapılmadı. Bu nedenle, assembler hack, 4.9'a geçene kadar mevcut olan tek çözümdür.