マクロを介してアクセスされるすべてのスレッドに固有のポインタを格納する必要があります。私は、これをシングルトンと静的なthread_local std :: unique_ptrオブジェクトで解決すべきだと考えました。ここでは、コードの簡易版である:C++ 11:GCC 4.8静的thread_local std :: unique_ptr未定義参照
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;
私は、GCC 4.8でこれをコンパイルする場合.1:
g++ -std=c++11 -pthread -o yay main.cpp yay.cpp
私が手:
/tmp/cceSigGT.o: In function `_ZTWN3Yay3yayE':
main.cpp:(.text._ZTWN3Yay3yayE[_ZTWN3Yay3yayE]+0x5): undefined reference to `_ZTHN3Yay3yayE'
collect2: error: ld returned 1 exit status
私は打ち鳴らすからより多くの情報を得るかもしれない期待していた、しかし、それは打ち鳴らす3.4と完全に正常に動作します:
clang++ -std=c++11 -pthread -o yay main.cpp yay.cpp
、プログラムを実行しているが、私は期待していた結果が得られます:
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
私は私がここで間違ってやっているかわからないんだけど、静的thread_local unique_ptrをOBJを持ってすることはできませんects?それは、intや '裸の'ポインタのような単純な型で動作します。
編集:
それは、これがhttp://gcc.gnu.org/bugzilla/show_bug.cgi?id=55800
EDIT2に関連しているバグである可能性があります:
回避策1:打ち鳴らすと、一つのファイルをコンパイル(yay.cpp)
回避策2(恐ろしい、移植不可能):最初にアセンブリにyay.cppをコンパイルし、追加する。
.globl _ZTWN3Yay3yayE
_ZTWN3Yay3yayE = __tls_init
アセンブリファイルへ
、ファイルをobjectにコンパイルし、残り
'getYay()'のプリプロセッサの置き換えがあなたを混乱させる可能性はありますか? – Tom
#defineを削除してYay :: getYay()を直接呼び出すと機能しません。 – linedot
バグレポートでは、コードのバージョンを大幅に減らし、回避策を示しています。たぶんあなたはそれを答えとして投稿することができます。 –