4

我声明一个变量__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'.

4

2 回答 2

13

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

实现这一点的唯一有效方法是制作变量static——这样做的原因是它导致变量被存储在线程本地存储池中而不是堆栈中。

例如在全球范围内:

__thread int my_id;

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

对于结构,如下:

struct xx {
    __thread int my_id;
};

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

struct xx {
    static __thread int my_id;
};

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

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

Thread Local Storage 上的Wikipedia 条目详细解释了这一点(包括一些陷阱)。

于 2012-10-22T16:31:56.477 回答
1

您需要将变量声明为静态。

于 2012-10-22T16:04:35.567 回答