线程本地存储GCC编译器

时间:2012-10-22 08:31:52

标签: multithreading gcc ubuntu

我宣布变量__thread int my_id; 我的平台和编译器的信息:

Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.1-9ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3) 

我使用标志-lpthread进行编译。 但编译器抱怨:error: storage class specified for 'my_id'

2 个答案:

答案 0 :(得分:13)

您已为变量声明了线程本地存储。变量的这种存储不能声明为堆栈上存在。使它成为struct / class的一部分隐式允许它在堆栈中。

实现此目的的唯一有效方法是创建变量static - 原因是它导致变量存储在线程本地存储池中而不是存储在堆栈中。

e.g。在全球范围内:

__thread int my_id;

将起作用,因为变量不在结构中。它可以自动放入线程本地存储池中。

对于结构,如下:

struct xx {
    __thread int my_id;
};

不起作用,因为变量最终可以在堆栈上,所以你需要使用:

struct xx {
    static __thread int my_id;
};

导致它被放置在线程本地存储池中,因此是一个有效的线程变量。

注意:我之前曾将变量描述为堆上。这严格来说是不正确的 - 变量取自在线程创建时分配的每线程内存块;我已将该术语重命名为“线程本地存储”池。此池具有特定于平台的大小,如果您有太多单独的__thread变量,则可以填充。

Wikipedia entry on Thread Local Storage详细解释了这一点(包括一些问题)。

答案 1 :(得分:1)

您需要声明变量static。